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]:
-
identity - data is quantised into entities called objects.
-
classification - objects with the same data structure and behaviour are
classified into classes.
-
polymorphism - the same operation amy behave differently on different
classes.
-
inheritance - the sharing of attributes and operations among classes
based on a hierarchical relationship.
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
- language simplicity - good enough for teaching novices
- O/O nature of language
- Power of language - the missing features I can live without
quite happily. For example, even though I can't do operator
overloading like I can in C++, I never thought much of that
feature anyway (since I couldn't add to the operator set like
I could in Prolog).
- Platform independance (I can write Mac/Windows applications
without having to leave my Linux box).
- Network-aware object classes that are simple to use
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