Java - Myth or Magic

Jan Newmarch

Distributed Information Laboratory

University of Canberra

Abstract

Java is hailed as the latest silver bullet to cure software ills by making all of your software Internet aware, running across all vendors platforms. This paper looks at the good, the bad and the future sides of Java, to try to give a balanced viewpoint.

Introduction

There has been a tremendous amount of publicity about Java since its release in May, 1995. The momentum of this seems to be still on the increase, with even a recent issue of Byte (January, 1997) devoted to the theme ``Can Java replace Windows?'' A large amount of this publicity (not Byte, of course) is confusing, exaggerated and more driven by Java versus Microsoft than other factors.

This paper attempts to tread a more balanced view of Java. This includes the good (sometimes excellent) features of Java and the bad (sometimes very bad) shortcomings of Java.

``Java'' as a generic term includes two things: Java the language and Java the object libraries. The good and the bad need to be distributed between these two. The language is more stable than the libraries and thus less fixable. Many adverse comments on ``Java'' refer to the libraries rather than the language, and these are more rectifiable.

The structure of this paper is as follows: major areas of ``Java'' are dealt with in turn: the claims about Java; graphics; animation; graphical user interfaces; platform independence; networking; internationalisation; and documentation. Within each area the positive aspects are discussed, but these are then followed by the negative aspects. Where appropriate, the future directions addressing changes are discussed.


What is Java?

Java is the programming language of the Net

Research into parallel and distributed languages has been intense in Computer Science for many years. Network topologies, communication models, language structures, even hardware such as the Transputer, have been the subject of much investigation.

Despite all this, the major distributed processing models that users commonly come across are things like email, network file systems, an increasing number of client/server applications (often database with a GUI frontend), and - recently - the Web.

The Web is now synonymous for many people with the Internet that underlies it, and usage figures support this. Distributed programming to many will be programs that affect their Web browser, and wander through Web documents on their behalf.

Many mechanisms have been attemped to bring programming to the Web. These include Forms with CGI scripts, JavaScript, VBScript, plugins, etc. Of all these, Java is the most flexible and the one with the most potential to be delivered across all platforms. Unless things go astray, Java is set to be the primary language for Web programmers.

Java is a better C++ than C++

C++ is an object-oriented language developed out of C. It maintains a high degree of backward compatability with C, with most of the O/O features added to a core of C. These extra features, plus a general tightening up of many C rules, have led to the claim (generally accepted) that ``C++ is a better C than C''.

C++ is a complex language, though. It still allows all of the dangerous operations of C, such as pointer arithmetic. The interplay between C features and C++ features allows quite grotesque programs to be written. Some of the C++ features are overly complex. I have tried to learn C++ several times, and generally walk away by about page 150 of advanced books when I no longer understand what on earth is going on. I do not want to be an advanced C++ programmer, because I don't think I would enjoy the experience.

The Java designers couldn't cope with C++ either, because its unsafety wouldn't allow the kind of checks they needed for a network language. So out with the unsafe features: that took out a lot of C, and a lot of C++ too. What you have ended up with is - in my opinion - a much nicer, safer, and more productive language. I was converted to Java within days of downloading the language specification, and it has been my programming language of choice since about November, 1995.

Java is certainly a better O/O language than C++. Is it a better C++? That depends on how much legacy C code (or legacy C programmers) you have to maintain.

Conversations with some ``mixed shop'' C++ and Java programmers suggest that even their C++ code is starting to look more like Java anyway as they stop using the more dangerous features of C++, using instead the styles, classes and paradigms of Java.

Java is Sun's "secret weapon" against Microsoft

Well, it isn't exactly secret. Is it a weapon? Sun have an enviable record for building open systems, and promoting standards that vendors can conform to in a cooperative manner.

Microsoft have been, shall we say, a little more aggressive in promoting proprietary ``open'' systems. They also have a healthier bank balance and are the dominant force in IT.

Java has the potential for undermining the importance of proprietary systems. It can do this by sitting on top of them like it can on a number of other systems. It is potentially O/S independent, so is a weapon against any proprietary system, be it Windows 95, Apple, or even Sun's Solaris!

It isn't secret. It isn't even aimed at any particular organisation. But it could affect vendors who seek closure on their systems more than vendors with an open attitude.

Sun have a program to certify Java applications as ``pure Java''. This is to guard against system-specific features (such as OLE) creeping into Java programs. The success of this program remains to be seen.

Java is the "in thing" for 1997

Oh heavens! Not only was it the in thing for 1996, but this momentum is being continued into 1997. Java in beta, and Java 1.0 caused all the fuss in 1996. Java 1.1 was released in March, 1997, and is an improvement on Java 1.0 in many minor and major ways. The Java Usenet newsgroups carry a vast amount of news, across half a dozen subgroups.

Vendor support for Java for Java is impressive, with IBM and Oracle being noteworthy (along with Sun of course). Even Microsoft are supporting Java (with a few hiccups).

Some Universities (such as the University of Canberra) are switching to Java as an early programming language. Short courses are blossoming.

Adverts are appearing in larger quantities for Java - not a fraction yet of the C++ ads, but growing.


Java is a killer language (positive)

It is an O/O language

Object oriented languages possess four characteristics [Rumbaugh 91]: Java possesses these characteristics. Some languages such as Visual Basic or JavaScript miss out on inheritance, which greatly weakens the structural capabilities of the languages.

C++ is also an O/O language according to this definition. However, because most C programs are also legal C++ programs, C++ is also a procedural language. C++ lacks the ``purity'' of Java in O/O terms.

You can't avoid objects in Java. This gives a kind of ``clunky'' start to most programs, in which you have to define an object with a main() method to get the program going. Apart from this, the pure O/O approach works well - you don't have stray functions that don't belong to objects, like you can have in C++.

It shares syntax with C

Whenever the language wars start, the pragmatists sit back and say ``C is the second most popular language to Cobol''. Computing students demand C in their courses, because they perceive the skill of being able to program in C is important to their employability.

Within any particular programming paradigm, the syntax is really only a skill issue. However, it is a tedious issue requiring time to acquire. If languages can share syntax within the same paradigm then this time is saved. Better yet if languages can share syntax across paradigms - this reduces the non-essential learning time.

Most C constructs work in Java. There are minor variations. For example, the following statement is interpreted differently in C, C++ and Java:

for (int n = 0; n < max; n++) ...
In C you can't declare a variable in a for loop. In C++ it declares n till the end of the function. In Java it declares n only for the following block. These syntactic differences are minor: more important is the recognition of the for loop across languages.

No pointer dangers

All objects in Java are handled ny means of a pointer to an object structure. Pointers certainly exist in Java. However, pointer arithmetic does not, and pointers as data types do not exist. This removes many of the pointer dangers that plague C and often C++ programs.

The relation between arrays and pointers is also missing. Since array bounds are checked as well, this removes the possibility of walking off the end of an array or string.

Objects and primitive data types have variables initialised to ``sensible'' values (null for objects). This also helps to prevent stray pointer values.

No funny parameter mechanisms

C has pass-by-value only. However, since you can take the address of any item and pass that by value, it allows a kind of pass-by-reference. C++ adds an explicit pass-by-reference so you can end up with three styles of parameter handling.

Java only has pass-by-value. Objects are already represented by addresses so these are passed without having to do address manipulation. Other primitive data types such as int are also passed by value. This gives only one style of parameter which is simpler.

Automatic garbage collection

Memory allocation and deallocation problems are a serious cause of bugs or memory leaks in both C and C++. Garbage collection is automatic in Java so there is no need to worry about it. Failures in memory allocation raise exceptions which are relatively easy to handle.

The use of a builtin garbage collector has the potential to slow down the application, and may cause problems in realtime systems. The collector runs as a low priority thread to minimise such problems.

Threads

Java is multithreaded. Threads are implemented by monitors but this is not visible to the programmer. Synchronisation of threads is accomplished by locking on objects for programmer declared methods. The priority of threads can be set programmatically.

Current implementations of threads use different scheduling models. This can lead to different behaviour on different systems.

Easy to learn

For the C or C++ programmer there is little extra syntax to learn. Because so many constructs are not present in Java there is little to learn about the interplay between different language features (such as the similarities and differences between pointers and arrays in C). A programmer knowing C and some O/O can pick up most of Java in a few days.

Because of the generally good behaviour and simplicity of the langauge, Java has been adopted as a first year programming language for Computer Engineers at the University of Canberra.

Java is a killer language (negative)

Weak multiple inheritance (specification, not implementation)

Java has single inheritance. A class can only inherit methods and instance variables from one parent class (which of course can inherit from others). Many O/O languages (such as Smalltalk) are also single inheritance. An inheritance ``graph'' is a tree.

In multiple inheritance, a class can inherit from more than one class simultaneously. C++ uses multiple inheritance. An inheritance graph is a directed graph without cycles. Multiple inheritance can allow a finer encapsulation of beahviour. For example, a class can inherit iterator behaviour from an interator class and windows from a windowing class simultaneously.

A major problem occurs with multiple inheritance: if a method with the same signature is defined in two classes and is inherited, then a choice has to be made as to which implementation to inherit. C++ has complex rules to choose.

Java has a simplified multiple inheritance model to get around this: you can inherit multiple specifications without implementation. Then there is no choice problem because there are not multiple implementations to choose between.

The weakness in this is that in about half of the cases where multiple inheritance is required, implementations should be inherited. These are missed in the Java model.

Slow

Java is defined to be implemented on a virtual machine. This is an old idea, used in UCSD Pascal, Prolog, and many other languages. The virtual machine is interpreted on each architecture that ``runs'' Java. This gives machine independance, with only the interpreter requiring porting (this is why threads run differently on different systems as the local threads mechanisms differ).

Any layer of interpretation adds an order of magnitude to execution time. With the extra checks that Java has, a Java program runs about 20 times slower than a corresponding C++ program.

In some circumstances this does not matter much: in a windowing application so much time is spent in the windows code written probably in C (for speed) that the small amount of Java code executed doesn't slow things down much more. Look at the success of Visual Basic for a similar situation. In time-critical situations it can make a difference, of course.

Where speed matters, there are two solutions: code the critical code in C as a native method, or use just-in-time compilation. Both of these are system-specific solutions. Native methods require a pre-compiled dynamic link library to exist on the machine to be loaded and called by the Java program. Just-in-time compilation compiles methods to native code just before execution, and requires the Java virtual machine interpreter to be a compiler as well.

A non-solution that is often asked for is native-code compilers. While it would be relatively easy to produce them, they would destroy the platform-independance of compiled code. For the same reason, the language does not include conditional compilation instructions, usually used to customise code to specific platforms.

No generics

There are many occassions where parameterised classes are useful. For example, you may wish to have a Stack of Integer or a Stack of Window. One way, which can only be used when all classes inherit from a common Object (like Java) is to use a Stack of Object and apply lots of runtime tests for specific types. This is clumsy.

Generics allow methods to be defined to act on a parameterised data type. Ada and C++ both allow this. A particular generic class is instantiated with a particular class (say Integer) as parameter. Java is missing this.

No low-level access

You can't poke at memory locations, read from ports, etc. These are not part of Java or any of the standard libraries. Part of the reason for this is security. So you can't do things like write a device driver in Java.

If you want low-level access, you must write native code methods and ensure that the DLL is available where the program runs.

Few low-level data types

Java has removed the machine dependencies of C: for example, int is 32-bit signed. 64-bit or 16-bit integers are not available. The set of low-level types is strictly limited also, but is improving with each release. Again, if you want machine-dependant stuff, you need to do it with native methods.

Intrusive exception handling

Exception handling has been borrowed from C++. A colleague much impressed with Eiffel is very unimpressed with this technique. It does mix up exception handling code with ``ordinary'' code and is fairly messy. It is the equivalent of checking system calls in C where the system call gets wrapped up in a boolean success/fail test.

Java is a killer language (future)

Speed is being addressed by Just In Time compilers. Because they only compile code that is actually executed, in some cases they are faster than downloading and executing all of a large native code application.

Low-level access can be met by encapsulating native code in native methods. So a device driver has a small amount of native code and a large amount of Java code. This, after all, was the reason C proved to be so successful in writing Operating Systems: 1000 lines of Assembler plus 100,000 lines of C. The principle is exactly the same.

Language extensions will come slowly, if at all. The major extension in Java 1.1 - anonymous classes - is a strange one. Few reasons seem to have been advanced for its purpose and it does introduce some problems.


Java does graphics (positive)

Java contains a class Graphics to allow respectable graphics programs to be built. Several Java packages have used these to add new graphics components to the basic AWT set, with ``raised'' shaded areas in different colours, suitably outlined.

Java does graphics (negative)

Restrictions

There is a strictly limited set of drawing functions. These include: drawLine(), drawRect(), and similar functions. These functions in turn have severe limitations: for example, lines can only be drawn one-pixel wide. To draw thicker ones, you need to draw lots of them, and this doesn't always work due to jaggies.

No optimisation

Some native windowing systems optimise certain operations, such as drawing horizontal lines one pixel wide. The Java library does not attempt to spot these, passing them straight through to the underlying native system. If optimisation is performed at the native level Java can take advantage of it, but not otherwise.

No tricky stuff

You can't do fancy things like changing the shading across a window. The graphics API does not include any special effects.

No 3D stuff

The graphics library is strictly 2-D. There are various extension libraries to support VRML, but these are not yet part of the standard libraries. I suspect that full Java support for 3-D may founder for a while due to proprietary 3-D kits.

New GUI objects

The Java GUI does not contain all of the widgets that applications might desire. New widgets may be written entirely in Java using the drawing functions to define their appearance. Unfortunately, appearance is a platform-dependant concept, so new widgets tend to be Windows widgets or Motif widgets, no matter what platform they run. In other words, platform-independant GUI drawing functions are not available.

Java does animations (plus)

Bt now most people have seen the ``steaming Java cup''. Many other Web pages use similar animations. These are relatively easy to build.

Java does animations (minus)

Moving gif

Animations are accomplished by loading a set of gif files and displaying them one after another. This limits the size of the animation since large files take a long time to load across the network, and also the number of files forming the animation. Animation is really just ``moving gif''.

MPEG

There is no MPEG or other movie display engine available in the Java libraries as yet.

No animation engine

There are no animation engines in the Java libraries as yet.

Java does animations (future)

A Macromedia engine is written in Java

A VRML engine is written in Java


Java does GUI (positive)

Java supports event-driven programming

GUI environments such as Windows, the X Window System and the Mac interface all use event-driven mechanisms to support user-driven computing. The AWT (Abstract Window Toolkit) is built above each of these and also uses an event driven model. This means that applications can be built that conform to the standard user-interaction models used nowadays.

Java has a large set of GUI elements

The AWT toolkit has menus, lists, text boxes, labels, buttons and many other standard user-interface elements.

There are two ways such GUI interfaces may be built: on top of the standard system GUI elements, or in a platform-independant way. Java chooses the first. So on Unix, the AWT is built on top of Motif, on Microsoft systems, calls are made into standard Windows elements. Many people (zealots) are annoyed by this - I think it is fine. There is no way that a Mac user will accept a Windows-style application, or vice-versa, so why try?

Java does GUI (negative)

Uses subset model of all GUIs

The current version of the AWT (1.1) only has elements that can be found on all platforms. So you can have text boxes, but you can't have Mac balloon help, Microsoft's OLE or Multiple Documents, because these are platform specific.

This is a serious issue: a Java application is not capable of exploiting all the features of any particular platform.

There are also some cross-platform GUI toolkits that adopt an overview approach, supplying missing elements where necessary.

Many common GUI elements missing

Motif has a set of dialogs, sucvh as WarningDialog, InformationDialog, etc. Other native GUI systems have similar sets. These are not yet available in Java, for no obvious reason.

You can build your own, but doing this purely in Java is prone to produce a solution in one GUI style only. While it is possible to determine the platform the program is running on, I haven't seen any attempts to utilise this information.

No drag and drop control

A common operation in all GUI systems is the ability to drag and drop information from one application to another. This is actually a fiendishly complex task, because of the type of the data to be transferred. For example, text may be selected in a Microsoft Word6 document and pasted into Interleaf running in an X Window emulator. In what format should the data be transferred? This requires negotiation between the two applications.

In Java 1.1 the basic elements for drag and drop are in place. However, a mass of code still needs to be written above this before it becomes workable.

No Object Link Embedding

OLE (and all its new variant terms) is a Microsoft-specific communications protocol which is very useful. While Microsoft may offer this as an extension, it is not a standard part of the Java libraries.

The problem here is a conflict of standards. There is CORBA with its variants (OpenDoc, etc) versus a more proprietary system. The GUI-specific side of OLE hasn't properly made it across all other GUI systems.

No Multiple Document Interface

Well, that ain't here either, for the same reasons.

Java has platform independence (plus)

Java source compiles to Java machine bytecode

The Java Virtual Machine is part of the Java specification. The code that is distributed in Java applets is in this byte-code format. This is machine-independant.

Java machine is interpreted

The use of a virtual machine means that a local interpreter is used to run each Java program. When the java chips become available, the interpreter will still be there, but at the micro-code level.

Same bytecode runs on different platforms

Because of the VM, the same code runs everywhere. Beware of native-code compilation of Java - you then lose the portability.

Java has platform independence (minus)

Java uses native look-and-feel

Java uses the native GUI libraries. Some zealots think everyone should use the Mac interface, or Windows 3.1, or Motif, or Tk, or ... (exclusively, of course).

Programming style satisfies nobody

Programmers who have invested a lot of time in one programming style may want to perpetuate this for ever. To be less cruel, there are often many ways of doing a particular task, and when the libraries lock you into a way you don't like then complaints result. As a concrete example of this, the event model of Java 1.0 was quite awful. The delegation event model of Java 1.1 is subtantially better than the old one, but there will still be complaints.

Each implementation has bugs

Java 1.0 has a large number of platform-specific bugs. Some of these are serious enough to damage functionality of applications.

Java 1.1 has only recently been released, and the number of bugs is unknown. In particular, the Windows95 version of the AWT has been completely rewritten, so is a good candidate for errors.

No platform-independent specification available

There is now a set of volumes: the Java API, written by the Java team. Regrettably one can still find holes in this, and some important aspects of Java 1.1 are not even mentioned in this specification.

Native code is platform-dependent, and vendor dependent

The Java libraries sit on top of native libraries. The Java VM is interpreted locally. There are plenty of opportunities here for incompability. The Microsoft interpreter at one stage displayed this by changing the garbage collector to a more opportunistic one, which broke the libraries of all other Windows95 Java vendors.

Java 1.1 has tighter specifications for the VM interpreter which should avoid such problems.


Java cruises the Net (positive)

Applets can be embedded in Web documents

All of the GUI elements and most of the other library classes can be used in Web documents to provide interactive applets on the browser side. This substantially increases the ability to build Web pages that conform to user expectations of GUI applications.

Code can be downloaded on demand

A potential area for Java penetration is in Intranets. Intranets are really just local networks (possibly utilising the Internet, too) that run Internet applications, and have an Internet ``look and feel''. That is, your Web browser will also be able to act as a FileManager, but will be able to display disks across the network as well as locally.

I suspect almost a con going on here - isn't this what network file systems have been delivering for years? The ability to download files as required for local execution. There are even some programs such as the Unix mailer pine which can display folders on remote machines.

Java cruises the Net (negative)

Security model restricts local capabilities

Applets cannot write to the local disk, or query its contents in any way. This means that a Java applet cannot damage or leak information about your local files. (Note that we are not talking about JavaScript here - that has a much weaker security model, that can for example access the history list of your browser.)

Although an applet can create multiple threads, it cannot create new system processes. This means that it cannot run local programs on its own behalf.

Security model restricts distributed capabilities

An applet can only form a network connection to the host from which the applet was loaded. This means that it cannot connect to other systems and pretend to be you, doing work (malicous or otehrwise) on your behalf. It also cannot explore within your firewall.

Security bugs have caused problems

There have been bugs in the past which have caused problems. These include being able to mail the contents of the local disk to another system. These bugs do not appear to compromise the basic security model, though.

Charging models not clear

Eventually software that the user will pay for will begin to arrive. Although a Java ``wallet'' will become available, how users will pay for the software is not clear. By time? By size? By other method?

Lacking transportability of Telescript

Java is not truly a distributed language like, say, Telescript. A Telescript program has the ability to halt execution, transport itself to a different machine and continue execution there. It

Java cruises the Net (future)

Security model will be made more flexible for Intranet uses

Browsers will need to be able to use these security models


Java has internationalisation (positive)

The Java char type uses Unicode 16-bit characters

This supports all European and Asian scripts

In Java 1.1, input and output methods in a single language mode are available (mixed mode, Chinese plus Thai for example, is not supported).

Locale methods are supported.


Documentation (positive)

There are over 150 books on Java, with many more in the pipeline

There is automatic generation of documentation from Java source code

The language is fully specified

The libraries are becoming specified

There is a large quantity of publically available source code

Documentation (negative)

Many of the books contain errors or are incomplete.

Many of the books refer to Java 1.0 without making this clear, while version 1.1 is now current.

The Sun specifications contain some errors


Further Information

Primary Sun site: http://java.sun.com/

Linux version: http://www.blackdown.com/

Gamelan: http://www.gamelan.com

Book info: http://lightyear.ncsa.uiuc.edu/~srp/java/javabooks.html

Java user groups exist in Canberra, Melbourne, Sydney

This article: http://jan.newmarch.nameug96/

Conclusion (positive)

Java is a practical route to platform independent code

It is a practical route for Intranet applications

It is a clean, easy to learn language

Hooks to many other systems such as ODBC, Corba are being built

Conclusion (negative)

Java should become stable enough and bug-free enough for mission critical applications in Java 1.1, although this relies on other parties: the browsers must be upgraded to support Java 1.1 and Just In Time compilers must become available.

The ``pure Java'' program must be able to deliver sufficiently powerful applications without proprietary extensions.

Java is not yet rich enough in connections for integration with other desktop applications

The ``killer'' Java application has not arrived yet, although Lotus may be on the right lines.

Conclusion (personal)

Java has been my language of choice for the last two years. This has been because of

I have been able to make this choice because I am not in a mission critical situation, and am able to experiment. If large amounts of money rode on my projects, then I would be wary - but not too wary. I would certainly be looking at network or applet projects as potentially large-payoff, but still reasonably high risk.

Myth or magic? Certainly a lot of hype! There is enough solid underpinning to Java that it is going to ride a long way, in lots of interesting directions that haven't been thought of yet. Where do you want to go tomorrow? I'm not sure, but I think the ride on the Java bus will be a lot smoother and more productive than, say, on the ActiveX bus!

References

[Rumbaugh 91] J. Rumbaugh, M Blaha, W. Premerlani, F. Eddy and W. Lorenson ``Object-Oriented Modeling and Design'', Prentice-Hall, 1991