|
|
To print: Select File and then Print from your browser's menu
-------------------------------------------------------------- This story was printed from ZDNet Australia. --------------------------------------------------------------
|
.Net develops advantages over Java By John Carroll, ZDNet US May 07, 2003 URL: http://www.zdnet.com.au/news/business/soa/-Net-develops-advantages-over-Java/0,139023166,120274276,00.htm
COMMENTARY-- Developers have a number of reasons for favouring one programming environment over another. For those attracted by good technology, .NET is worth a look. I used to collect comic books (or, read a heck of a lot of them and refused to throw them away, depending on how you look at it). That's impossible, you're saying. Programmers are serious people who don't have time for comic books, science fiction, role-playing games, and strange fascinations with a certain "Weird Al" Yankovic's cinematic magnum opus. But, surprising as it might seem, I did. I remember a certain hard-drinking character from a Hercules Limited Series by Marvel comics who resembled a small ninja turtle, sans mask. Well, to borrow a term used by this unknown character (the meaning of which I can't remember), I've been working my scroggies off. Given that my brain happens to be stuck deep in programming la la land (as opposed to where it normally sits, which is in a jar, labeled "Abby Normal"), I'm going to take a detour from my usual obsession with the state of the software industry and discuss some of the ways .NET is an improvement over Java. As I've noted before in Talkbacks, I've been programming Java in some form since JDK 1.0. Java development has a number of advantages over traditional environments which output machine language. .NET has the advantage of hindsight, however, and has improved on Java in a number of areas. Here are some that stand out from my most recent project (I could tell you what that project's all about, but then I'd have to eat you). It's worth noting that this article is somewhat more technical than my norm. This is unavoidable, as .NET, like Java, is essentially technology for enhancing developer productivity. Besides, at this point, I'd probably find a way to make Dr. Seuss stories sound complicated. 1. Standardised configuration:
Though XML parsers certainly exist for Java, Java components don't tend to be configured by XML files, particularly the components included as part of the core JDK. This isn't an oversight on the part of Java. Java came of age prior to the popularity of XML, and property files were a simple and easy way to allow administrators to configure applications with a text editor. In contrast, XML permeates every corner of .NET. So important is XML to .NET that the core CLR, the portion standardised by the ECMA and on its way to IEEE standardisation, includes XML parsing libraries. This means that every conformant CLR of necessity must include XML parsing libraries. XML is infinitely more flexible than property files, and that makes it a better standard configuration technology than property files. Lists of values are easier to represent in XML, the range of parsing technologies is larger, and the format is familiar to anyone accustomed to HTML. XML usage in .NET really stands out in the .NET configuration system. .NET configuration files contain XML, which conforms to a simple XML grammar. The name of this file depends on the type of application that is being run. For executable desktop programs (on Windows, ending in .exe), the name of the file is the name of the executable followed by ".config" (example: myapp.exe.config for a program named myapp.exe). In ASP.NET, this configuration file is called web.config, and is located at the root of the web application directory. The standard XML grammar for .NET configuration files is astoundingly simple. The base schema defines little more than tags by which to define custom XML parsing handlers. These handlers are called during AppDomain startup (the .NET abstraction for the .NET runtime, which I'll discuss later), and they return data objects which are cached at application scope and retrieved at runtime using the central ConfigurationSettings.GetConfig method. Handler creation is simple. As shown in this example, custom handlers merely implement the System.Configuration.IConfigurationSectionHandler. They are declared for local application using a "section" entry under the "configSections" block of the .NET configuration file. This defines the XML element names that will contain custom XML parsed by your custom handler. Microsoft includes machine-wide XML parsing handlers inside the centralised machine.config configuration file, which is a file from which every configuration file implicitly inherits. All configuration syntax used by components in the .NET Framework is implemented somewhere by a set of configuration handlers specified at some level in the hierarchy of .NET configuration files. You can extend this machine-wide configuration base by adding your own handlers to this machine.config file, or if the need arises, override existing handlers to handle custom configuration logic. For Java developers, the biggest advantage to .NET's configuration system is an end to property file proliferation. Property files multiply like rabbits in a large, Java-based web application, where aggregation of numerous third-party subcomponents is the norm. Since there is no global, process wide Java configuration standard, each subcomponent specifies its own configuration property file (the names of which, hopefully, won't clash) which must be included somewhere in the classpath (the classpath specifies where the Java management process (or "runtime") should look for the files it needs in the course of running a program). With .NET, every component knows to retrieve its configuration information from ConfigurationSettings.GetConfig, the data for which is built from a hierarchy of configuration files. This greatly simplifies administration of applications, and in my experience, has been tremendously useful as a development option. 2. Extensible metadata
Java Reflection goes way beyond the clunky IDL-derived type information found in CORBA and COM, as it is built on the information contained in the bytecodes used to represent the Java class. It was an innovation made possible by Java's transparent and well-defined internal structure, which just so happened to be the same feature that made it possible to run Java on multiple machine architectures. Not being the sort to ignore good ideas, Microsoft has included Reflection in .NET, and has ensured that it is defined as part of the core CLR (in other words, every conformant .NET runtime must support reflection). Microsoft, however, has taken reflection to the next level, allowing programmers to include custom information with a .NET class which can be retrieved using the .NET reflection APIs. This out of band information is used extensively by the .NET security system. By "tagging" methods with out of band custom attributes, programmers can tell the .NET security subsystem what sort of access rights it requires, or conversely, what rights it wants to ensure callers do not have. For instance, the ability to display a user interface is controlled by a "permission," and all code that is used to paint user interfaces (WinForms, as an example) is marked with a "Demand" for UI access. Code running in a context without this permission (in a daemon process, for instance) cannot display a user interface. In ASP.NET, SOAP extensions allow developers to customise the incoming and outgoing XML stream. This customisation is triggered through the use of a simple out of band metadata "tag" that informs the SOAP message filters of the class which needs to be loaded to customise the SOAP stream of data. This out of band information is retrieved at runtime using .NET Reflection. It is very easy to tag methods and classes with existing attributes in the .NET system. As this example shows (which is taken straight out of my CLR Proc Container freeware, the source code for which is now available for download), it is also easy to create custom attributes to carry out of band information of interest to your program. Customisable type information is an important addition to a programmer's toolbox, and even more important, makes your program simpler and easier to manage. 3. Assemblies
Assemblies serve a similar purpose, yet are decidedly different in style to jar files. Granted, they are used to package multiple class files into one distribution unit, but for that matter, Assemblies are the ONLY distribution unit for .NET classes since there is no such thing as a .NET ".class" file which sits on a disk drive as a separate entity. Assemblies, however, are a "harder" concept than jars, as they have unique identities in ways that jar files simply do not. As a "reflection" of the importance of Assemblies, you can retrieve the Assembly from which a .NET class was loaded using the .NET Reflection APIs. On any object, you can call GetType().Assembly to determine details of the assembly which defined the loaded class. The nearest comparable capability in Java is through use of the java.lang.Class.getPackage() method, though the amount of functionality available from an Assembly far exceeds what is available from the java.lang.Package object. The Assembly provides a great deal of useful information. Highlights include disk location of the assembly (normal in Windows dll's, but unknown in Java), version (the format of which is standardised, in contrast to the various java.lang.Package version properties, all of which are strings), and custom information included as part of the assembly during compilation. Assemblies always know the location from which they were loaded. This creates useful possibilities, such as applications that know how to look for certain pieces of information relative to the location of the Assembly on disk. Assemblies can also contain certain bits of custom information (e.g. Assembly-level metadata attributes) that can be used during runtime to control what rights code in the assembly has, or whether it is allowed to be loaded at all. Lastly, Assemblies can have cryptographically strong identities which can be used to programmatically distinguish them from each other. Such "strong named" assemblies have been signed with a private key, and it is this strong identity which allows .NET to run different versions of the same dll in parallel. The importance of this should be apparent to any Java programmer who has been forced to navigate the Java XML minefield on a large website that integrates products developed by a number of third parties. In Java, only ONE library that conforms to a certain interface convention gets loaded, usually the first one it comes across in the classpath. But all XML parsers implement the same set of interfaces, and thus are replaceable for one another, right? Wrong. First, there are a number of differences between versions of the XML interfaces. Second, even when they theoretically conform to the same interface, there are differences in implementation. For instance, one version might properly protect against simultaneous access from multiple threads, while another won't. XML is used by a lot of Java products these days. Unfortunately, though there seems to be a certain de facto convergence around the Apache Xerces parser, that convergence isn't universal, and it certainly doesn't imply convergence around the same Xerces parser version. There are workarounds, of course. You can do as I did and write a custom Java classloader that isolates a third-party product from the libraries loaded by the parent web application. That, however, is a non-standard solution, and a standard solution included as part of the base runtime would be a vast improvement. .NET offers such a solution in its ability to run multiple versions of an assembly simultaneously within the same AppDomain. 4. .NET Remoting
.NET Remoting doesn't define a standard protocol. Rather, it is little more than a set of configurable "channels" (transport layer handlers for dispatch over a network), Formatters (for defining the format into which objects will be serialised for transport over a network) and message sinks (for message customisation). The standard channels included with the .NET Framework are the TcpChannel (for sending data over socket connections) and HttpChannel (for sending over http, a protocol layer on top of a socket). The standard formatters are a Binary formatter, which, like JRMP, is more intended for .NET to .NET communication, and a SOAP formatter. Invocation of a remote object is set up as a chain of messaging handlers (including transport channels and formatters as special types of messaging handlers) that work together to make a call across a network. Channels for dispatch via SMTP or MSMQ exist in the wild, as do formatters that support XML-RPC. One of the more interesting thing about .NET Remoting, however, is the ability to configure remote objects using only external configuration files. The full class name of the object to be exposed, whether or not it is a singleton or a single call object, the transport it will use, what formatter it will use, and whether any custom messaging filters should be interposed somewhere in the messaging chain are all defined in the text-based XML configuration file for an application. This offers tremendous flexibility for applications which need it, as complex details about the characteristics of a remotely-accessible object can be tuned external to the compiled application. This is why I have been so adamant in the past that SOAP is no more a required part of .NET than any other protocol used for sending object data across a network. The SOAP Formatter is merely one option available as a serialisation format. ANYONE can create their own formatter and use it in place of the SOAP Formatter with little more than a change in a configuration file entry. In other words, if for whatever reason a company decides to shift to XML RPC from SOAP, all they'd have to do is get an XML RPC Formatter and specify its use in the configuration file. .NET Remoting is interesting technology, and even better, the full source code for a working implementation is included with the Rotor .NET CLR implementation (you can see it online here). Creating your own .NET Remoting extensions can be complicated, which is why access to the source for a working implementation is indispensable (and though I can't say for sure, I suspect from my own use of that code that it bears a strong resemblance to the code that actually ships with the .NET Framework). For a great book on .NET Remoting, check out Ingo Rammer's "Advanced .NET Remoting", from a! press. Conclusion
Of course, .NET is still a mostly Windows party, while Java offers the chance to work on a large number of platforms. As I've noted, however, Mono offers a complete implementation of the .NET Framework for Linux, and there are companies already who promote their .NET product's support for non-Microsoft systems. This support has nowhere to go but up, as technology innovators with an interest in non-Microsoft platforms see a business opportunity in offering Windows support alongside support for their favourite platform. It's certainly easier to make a business case for that client-side Linux startup when you can promote your products support for the large installed base of Windows users. People have a number of reasons for favouring one programming environment over another. For those attracted by good technology, .NET is worth a look. John Carroll is a software engineer living in Ireland. He specialises in the design and development of distributed systems using Java and .Net. He is also the founder of Turtleneck Software.
Copyright © 2009 CBS Interactive, a CBS Company. All Rights Reserved. |