Dr. Dobb's Journal January 1998
In the summer of 1995, I wrote the article "Java and Internet Programming," which appeared in the August issue of Dr. Dobb's Journal (available electronically; see "Resource Center," page 3). At the time, I was a member of the Java team at Sun and was working on the beta version of the HotJava browser. My 1995 article elaborated on the benefits of Java for Internet programming and represented the vision of the Java team at that point in time. It is now two-and-a-half years later and much happened. Among other things, together with Kim Polese, Jonathan Payne, and Sami Shaio, I left the Java team to form Marimba, a company that provides Java-based tools for managing, distributing, and updating network applications and services. What's become clear over the past couple of years is that Java is a great language and a great marketing success, but the question remains: Is Java ready for business applications?
Java was conceived in 1990 by James Gosling at Sun Microsystems, who started a project to create software for consumer electronics. After some initial frustrating experiences with C++, he decided to create a new language. The result was Java -- the language, libraries, and virtual machine. The project started as a grass-roots effort and remained secret until late 1994 when Java was first released to the general public. After its public release, Java quickly gained popularity in the developer community, picking up real momentum in May 1995 when Netscape announced it would support Java in its browser. A major seal of approval came from Microsoft in December 1995, when it licensed Java for inclusion in Internet Explorer. Since then, the project, which initially consisted of a handful of people, has grown to a 700-person organization within Sun Microsystems.
Although Java is a topic of much discussion and confusion, everyone seems to agree that it has much technical merit. Java isn't rocket science and it doesn't change the programming paradigm. Instead, it is a practical and powerful solution for today's networked programming environments. Java's major strength is its clear and detailed language definition. James Gosling, Guy Steele, and Bill Joy define each aspect of the language in minute detail in the holy bible of Java programming The Java Language Specification (Addison-Wesley, 1996; and http://www.javasoft.com/docs/books/jls/html/index.html). The Java syntax and its semantics are already well established, mostly due to its incredibly precise definition.
I had to program C++ for many years before I joined the Java project and I drew on that experience to influence the development and specification of the Java language. C++ is too complex for most programmers, it is ill defined, does not behave the same way across platforms, and not all compilers support all its features. The Java language does not suffer from these problems because it is much simpler and much better defined.
I'm glad the Java language has changed little over the past couple of years. Stability is important for the widespread adoption of a language, as too much change makes software maintenance tedious and expensive. Besides a few new extensions like nested classes, nothing much has been added in the past few years. That so little has changed, even after extensive public scrutiny, is a testimony to the maturity of the language. In short, the Java language is largely complete. It is baked.
Is there anything that should be added or changed? I always felt that we should add enumerated and parameterized types, but I worry that this may make the language more complex than strictly necessary. The strength of Java is not that it is incredibly powerful or sophisticated. Its beauty lies in the fact that it is simple, concise, clean, and well defined. Many programming languages exist that are much more sophisticated and powerful, but Java is attractive because of its simplicity. Java is more than just a language -- it is a way of life.
That Java has been criticized for its poor performance surprises me. Raw Java performance has greatly improved in the past few years with the help of just-in-time compilers and fast interpreters. Raw speed is not a problem anymore. It is no longer true that Java is 3 to 4 times slower than native code -- it is actually only 20-40 percent slower. Don't believe benchmark tests that can be construed to prove almost anything. If you want to know the bottom line, write some code, and see for yourself. In my experience, most applications -- and in particular I/O-bound ones -- are not noticeably slower. Hard-core critics will always be able to find an application for which Java isn't ideal, and use it as an example.
There is more to come. Sun has announced a new virtual machine, code-named "HotSpot," which promises performance equaling or exceeding that of C++. This new virtual machine relies heavily on sophisticated dynamic compilation techniques pioneered by Dave Ungar in the Self project (http://self.smli.com/). In some cases, the performance of this virtual machine exceeds the performance of C++. This is possible because C++ is statically compiled for the common denominator CPU, while HotSpot morphs its executable Java image in real time to fit your processor like a glove. Cool, huh?
Java's window system toolkit, the Abstract Window Toolkit (AWT), provides a simple but effective API that relies on the platform's native windows system for displaying widgets. Sami Shaio and I wrote the first version of the AWT in the summer of 1995. The predecessor of the AWT was based entirely on Xlib, the X Windows graphics library, and did not provide much support for widgets. We wanted a set of predefined widgets written entirely in Java, but there was pressure from Netscape to provide a native look-and-feel on each platform. Consequently, we decided to add the AWT peer mechanism, and use the widgets of the underlying window toolkit to provide the look and feel. This turned out to be an unfortunate decision because it proved difficult to support native widgets on each platform, and simultaneously provide consistent semantics. Ironically, less than a year later, Netscape started the development of its Internet Foundation Classes (IFC) toolkit, which does not use the native look-and-feel at all. Instead of focusing on providing a native look-and-feel, I wish we had spent more time developing a powerful graphics model.
Because of the AWT shortcomings, Sun, Netscape, and Microsoft are developing additional toolkits written entirely in Java that provide a look-and-feel independent of the underlying system. In a few years, Java-only widget toolkits will be commonplace, and the AWT will only be used to provide the most basic services. Which toolkit will predominate? Most likely there will be several. Sun's Java Foundation Classes (JFC) will become the standard toolkit in most Java environments, but other toolkits that provide a different focus will also find their niche.
There are currently several solutions for distributed computing in Java, the most important being Sun's Remote Method Invocation (RMI), the OMG's CORBA, and Microsoft's DCOM. Distributed computing is important for Java because the language was designed for networked applications. How do these solutions compare? Because of its nature, the most important aspect of any distributed computing solution is interoperability -- and that's why DCOM is not really an option (since it is a proprietary solution). An important standard in this area is OMG's Internet Inter-Orb Protocol (IIOP), which defines a language-independent protocol for distributed computing based on CORBA.
RMI is a standard component of the JDK 1.1 (see "Java RMI in Practice," by Martin Remy, Dr. Dobb's Special Report on Software Careers, Fall 1997; also available electronically). The RMI is a Java-friendly solution, but does not provide interoperability with other languages. It relies heavily on the Java serialization APIs when passing objects by value. Although RMI currently uses its own on-the-wire protocol, Sun has promised to migrate the RMI to use the IIOP in the near future.
In addition to RMI, various CORBA implementations are available, the most commonly used being Visigenic's Visibroker, which provides a Java-friendly, IIOP-compatible CORBA implementation. Although there is a licensing fee involved, the terms are reasonable, and the Visibroker client is included in every copy of Netscape's Communicator.
So which is the better solution -- CORBA or RMI? Both approaches require you to significantly modify code when you want to make Java objects distributed. For example, each method in an RMI interface must declare that it may throw an RemoteException. This means lots of catch statements will be littered throughout your code whenever an RMI method is used. Some distributed computing experts argue that this is the correct thing to do -- and they are probably right. In the real world, however, this can become cumbersome. Also, these changes require an immediate full commitment to the RMI because it will affect virtually every piece of code that uses or implements a remote RMI object.
The CORBA approach is somewhat cleaner since it does not require the declaration of remote exceptions, but does put up other hurdles. CORBA interfaces are most easily implemented in a language that supports multiple inheritance (C++, for instance). As a result CORBA-to-Java mapping can be somewhat awkward, especially as your objects get more complex and implement multiple interfaces. Visibroker provides some tools for automatically creating so-called "tie" objects that alleviate the pain somewhat, but again you'll find it affects almost all the code that deals with remote objects.
Both the RMI- and CORBA-based approaches generate stubs and skeletons, which are used to implement the on-the-wire object protocol. The RMI generates stubs and skeletons for implementation classes, which means that it can support object equality. However, you will find that this also creates dependencies between clients and servers. Users of a remote RMI object need to know not just the interfaces that the object implements, but also must have access to the correct implementation stub. This isn't acceptable in a widely deployed system, because the whole point of using interfaces was to eliminate dependencies on the object implementations in the first place. The seemingly simple answer to this problem is the automatic distribution of the correct implementation stubs from the server to the client. Java is the ideal language for doing this. However, Java veterans will quickly realize that this option, although clever, is fraught with problems. Downloading a piece of code from a remote location is possible, but it requires cooperation from class loaders and security managers, and is unlikely to work in existing environments unless modifications are made.
Although RMI currently does not use IIOP, Sun is migrating it to use IIOP. This is a concern because it will have implications on RMI semantics, and I am not sure if RMI will be able to support object equality as it does today. IIOP support will trigger significant changes in the design of RMI, and it will result in an RMI 2.0, which is not necessarily backward compatible.
I haven't yet decided what the best solution is for distributed computing in Java. The RMI is Java friendly, but Visibroker also provides excellent Java support (you never have to write a line of IDL to successfully create and use CORBA objects, which is cool). But both RMI and CORBA provide challenges that need to be resolved before a definite winner can be declared. Whatever the solution is, it should be based on IIOP, which is quickly becoming the industry standard. And whatever the ultimate solution is, it should be based on IIOP and be an integral part of every Java implementation.
Does Java live up to its promise of true platform independence -- Is it portable as some people claim? Unfortunately, this question cannot be answered with a resounding "yes." Actually, the portability of a Java application is truly amazing. It is absolutely possible to write complex multithreaded applications with complex user interfaces that run immediately and without recompilation or modification on many platforms. And not just wimpy applets either -- I'm talking about sophisticated, networked, interactive, multimedia, and multithreaded applications. This is an incredible achievement, and probably one reason why Bill can't sleep at night.
But the devil is in the details. Actually, the devil, in this case, is in the libraries -- in particular, the AWT. The Java libraries provide access to sophisticated operating-system services, and it has been a challenge to make these truly identical across multiple platforms. Sun has been slow in providing exhaustive test suites that guarantee compatibility for Java environments. The 100% pure Java program has been helpful in promoting the notion of truly portable Java applications, and it has made Java live up to the promise if true portability.
The bottom line of Java portability is that it is excellent, especially if you know what problems to watch out for -- sometimes it is the browsers that you should watch out for. The Java Virtual Machines in browsers can be buggy, slow, and incomplete. This is partially due to the challenge of innovation. As Sun improves the Java APIs, browsers are often slow to follow because of release schedules and resource constraints. The result is that every browser implements a slightly different and sometimes incomplete version of Java, which makes portability a challenge for the developer.
Whether or not Java will become an open standard is an interesting question, but at this moment it hardly matters because most environments implement Java fairly accurately. Whatever happens, the end goal remains the same -- a ubiquitous, vendor-independent, programming platform for the Internet. But not everybody wants that. Java is the first technology that poses a threat to Microsoft's grip on the operating system, and this has not gone unnoticed.
The big issues do not revolve around the legal details involving Microsoft's license. Instead, I am curious to see whether Microsoft will ship the JFC and RMI, instead of (or in addition to) its Application Foundation Classes (AFC) and DCOM. The exclusion of these APIs could easily split the Java platform into two camps. Let's hope this doesn't happen, because from a programmer's perspective, it is important to know what is part of the standard and what isn't. Variations must be eliminated where possible.
Sun should proceed quickly in making Java an international standard, but unfortunately this may have implications for the Java trademark. Despite the slow start, I am hopeful that Sun will do the right thing and make Java a standard that can't be ignored. It is quite acceptable if Sun retains a certain amount of control over the language, as long as they don't abuse it. So far, they've done a great job.
So, is Java ready for business applications? The answer is "yes," but with caveats. The biggest challenge of a business application is deployment. Browsers are not ideal as deployment platforms for applications, so you may want to look for alternatives.
The distribution and management of Java applications is an area that has been ignored. It is important that Internet applications become easier to manage and cheaper to deploy than legacy applications. Client-server computing was originally touted as a way to reduce cost, but it turned out to be more expensive than mainframe computing because it was much harder to manage. The same can't be allowed to happen with Internet applications.
After almost two years at Marimba, it is clear that Java has made a difference in our ability to produce products. We have shipped two major releases of several products in several spoken languages on several platforms in less than 18 months. This would not have been possible had we used any other language. Java provides great leverage and allows us to support more platforms and products than we would have believed possible.
The biggest advantages of Java for business applications are productivity, portability, and robustness. Our engineers are much more productive in Java because they like the language. Our products run on more than eight platforms without recompilation. And despite inevitable programming errors, our software never crashes because Java provides a safety net that has made our products significantly more reliable than their C++ equivalents would have been.
There is a clear business case for Java: It is cheaper to deploy, easier to manage, more portable, and more flexible -- and your engineers will be more productive. Java is now a major language for database applications, and it is a great language for server programming. Unlike a few years ago, there are now lots of excellent tools available.
Java is not just a language for adding interactivity to web pages. Ignore all the politics and hype. Java is simply the most cost-effective choice for Internet and business applications.
DDJ