Tags: abstract 1, computer science university, de facto standard, distribution format, executable content, internet java, java internet, java virtual machine, java virtual machine jvm, launch, michael franz, mobile code, mobile software, portable software, software components, sun microsystems, technology demonstration, thomas kistler, university of california irvine, web browsers,
Does Java Have Alternatives?
Michael Franz and Thomas Kistler
Department of Information and Computer Science
University of California
Irvine, CA 92697-3425
+1 (714) 824-4825
{franz, kistler}@ics.uci.edu
ABSTRACT 1 INTRODUCTION
At first sight, Java's position as the de-facto standard for In the short time since its launch, Sun Microsystems's
portable software distributed across the Internet seems Java technology has become almost synonymous with
virtually unassailable. Interestingly enough, however, it is portable software that can be distributed across the
surprisingly simple to provide alternatives to the Java Internet. Java's pre-eminent position is reinforced by the
platform, using the plug-in mechanism supported by the fact that built-in support for its distribution format, the
major commercial World Wide Web browsers. Java Virtual Machine (JVM), is now not only part of
We are currently developing a comprehensive practically every World Wide Web browser, but is starting
infrastructure for mobile software components. This is a to appear even within operating systems. Yet in spite of
long-term research activity and not directly related to Java the de-facto adoption of Java by most of the Internet
and the World Wide Web. However, purely as a community as the standard platform for encoding
technology demonstration, we have recently started a small executable content (at least for the time being), it remains
spin-off project called "Juice" with the intent of extending surprisingly simple to provide alternatives to this platform,
our experimental mobile-code platform into the realm of even within the context of commercial browser software.
the commercial Internet.
We have created such an alternative to the Java platform
Juice is implemented in the form of a browser plug-in
and named it "Juice". Juice is an extension of the first
that generates native code on-the-fly. Although our
author's earlier research on portable code and on-the-fly
software distribution format and run-time architecture are
code generation [3, 4, 5]1. Our current work is significant
fundamentally different from Java's, once that the
on two accounts: First, Juice's portability scheme is
appropriate Juice plug-in has been installed on a Windows
technologically more advanced than Java's and may lead
PC or a Macintosh computer, end-users can no longer
the way to future mobile-code architectures. Second, the
distinguish between applets that are based on Java and
mere existence of Juice demonstrates that Java can be
those that are based on Juice. The two kinds of applets can
complemented by alternative technologies with far less
even coexist on the same web-page.
effort than most people seem to assume. In fact, once that
This, however, means that Java can in principle be
Juice has been installed on a machine, end-users need not
complemented by alternative technologies (or even
be concerned at all whether the portable software they are
gradually be displaced by something better) with far fewer
using is based on Juice or on Java. In light of this, we are
complications than most people seem to assume. As
surprised by the widespread belief in the myth that, in
dynamic code generation technology matures further, it
order to be portable, all executable content must
will become less important which code-distribution format
necessarily be encoded in Java. In the short term, this myth
has the largest "market share"; many such formats can be
may lead to some ill-founded technology decisions.
supported concurrently. Future executable-content
developers may well be able to choose from a wide range Just as with Java, there are three major components to the
of platforms, probably including several dialects of Java Juice technology: 1) a source language and an API in
itself. which Juice applets are programmed, 2) an architecture-
neutral distribution format, and 3) an environment for
Keywords
executing Juice applets, which in the current
Mobile code technologies, plug-in browser extensions, on-
implementation of Juice is supplied in the form of a
the-fly code generation, Java, Juice, Oberon.
1
note that this earlier work on mobile code predates Java by
several years
browser plug-in that generates native code on-the-fly. On Oberon was defined several years before Java.
all three accounts, Juice differs considerably from Java, yet
Oberon is a much smaller language than Java, having been
from the web-browsing end-user's perspective, there is no
designed almost as the "essence of a programming
obvious difference between Java and Juice applets.
language". For example, Oberon provides no language-
In the following, we will introduce the three components level support for concurrency. While we agree with Ted
of the Juice platform: source language, distribution format, Lewis [7] that Java's concurrency scheme falls
and dynamic-compilation environment. We will then use a disappointingly short of the existing state-of-the-art ante,
simple example for presenting Juice and Java side-by-side, Oberon offers no built-in support for concurrency at all.
arguing that the choice of a particular mobile-code For the project described here, we have not attempted to
solution may simply be a matter of personal taste, rather change the Oberon language and have therefore only
than a technological necessity. Luckily, it is the applet studied applets that can be constructed from the set of
developer that needs to make this choice; the end user need language features in the intersection of Oberon and Java.
not know any of it as multiple mobile-code technologies, However, we note that this is only an incidental effect of
such as Java and Juice, can happily coexist, even on the our choice of Oberon as a source language and in no way
same web page (Figure 1). limits our claim about Java's substitutability in principle.
Moreover, we note that some current optimizing
2 PROGRAMMING JUICE APPLETS
translators for Java also exclude the concurrency
Juice applets are programmed in the language Oberon
capabilities of the Java language [11], because support of
[16], a direct successor of Pascal and Modula-2 that was
threads has a performance penalty associated with it [14].
defined by Niklaus Wirth (Pascal's original creator) in
1988. Oberon is surprisingly close to Java in spirit; like A Juice-applet development tool-kit is now a standard part
Java, Oberon is based on the principles of simplicity and of the Oberon software distribution from ETH Zurich and
safety. Oberon enforces type-safety by mandating array- UC Irvine [13] for Apple Macintosh and Microsoft
bounds checking and prohibiting pointer arithmetic, it Windows. Besides providing a full implementation of
automates memory management through the provision of Oberon System 3 [6], it supplies a set of Juice-specific
garbage collection, and provides source-level APIs along with a compatibility-box recreating the
modularization facilities along with dynamic loading. environment of a browser plug-in within the Oberon
Superficially, but not entirely untrue, one might argue that environment. Hence, Juice applets under construction can
Oberon is a subset of Java with Pascal syntax, except that be tested interactively without having to exit the
Figure 1: Java Applet (left) vs. Juice Applet (right)
development environment. processing step is needed to re-create the lost structural
information. This is not necessary with slim binaries. This
3 DISTRIBUTING JUICE APPLETS
argument applies not only with respect to code
Juice's code distribution format, which we call "slim
optimization, but also for code verification: analyzing a
binaries" [2], is based on the Ph.D. thesis work of the first
mobile program for violation of type and scoping rules is
author [4]. The slim binary format differs considerably
much simpler when the program has a tree-based
from virtual-machine representations such as p-Code [12]
representation than it is with a linear byte-code sequence.
or Java byte-codes [8] in that it does not resemble
executable code. Instead, it is based on a tree-shaped Our present implementation of slim binaries is in so far
program representation as is typically generated transiently restrictive as it supports exactly one source language,
in optimizing compilers. This intermediate tree- Oberon. In this respect, our system presently doesn't do
representation is then compressed by merging isomorphic much better than abstract-machine-based portability
sub-trees, using a variant of Welch's classic LZW schemes in which the instruction set of the virtual machine
algorithm [15] that has been specifically adapted towards is explicitly crafted to support a particular source
compressing program trees. Being a dedicated algorithm, language. While we do not foresee any difficulties in
it achieves remarkable information densities (Figure 2). encoding syntax trees for other languages, possibly even
using the identical format, the suitability for other
Using a tree-based intermediate code-representation has
languages has yet to be established by an actual
the disadvantage that it is not well suited for
implementation.
interpretation. While representations such as p-Code and
Java byte-codes permit random access, i.e. one can jump We have therefore recently started a follow-up project with
20 instructions forward in the code and resume the aim of constructing a compiler that takes Java as its
interpretation, this is not possible with slim binaries. Each input, but generates slim binaries instead of Java byte-
symbol in a slim-binary-encoded program can be codes as its output. This tool will not only enable a more
interpreted only in the context of all the symbols that direct comparison of our code representation and our
precede it. Because of this characteristic, our dynamic compilation architecture with their respective
implementations have eschewed interpretation of the Java counterparts, but it will also aid the wider discussion
intermediate form from the very beginning and have of platform-independent mobile-code solutions by
incorporated on-the-fly code generators [4, 5]. disengaging the question of source languages from the
separate issue of finding suitable distribution formats.
On the other hand, reading a slim binary in our system re-
creates the original tree data-structure, which is not only 4 EXECUTING JUICE APPLETS
an almost ideal input for an optimizing code-generator, but The only part of Juice that is visible to end-users is a set of
it also makes code verification relatively easy. The slim platform-specific plug-ins for Netscape Navigator and
binary format preserves structural information such as Microsoft Internet Explorer. Once the appropriate Juice
control flow and variable scope that is lost in the transition plug-in has been installed on a user's machine, the user
to linear representations such as Java byte-codes. In order can then view and execute Juice content in the same
to perform code generation with advanced optimizations manner as Java applets. Hence, after installation of the
from a byte-code representation, a time-consuming pre- plug-in, users can no longer distinguish between Java and
Slim Binary 100%
LZSS Compressed i386 Binary 156%
LZSS Compressed Java Byte-Codes 172%
LZSS Compressed PPC601 Binary 219%
LZSS Compressed Source Code 277%
Java Byte-Codes 242%
i386 Binary 284%
PPC601 Binary 344%
Source Code 665%
Figure 2: Relative Size of Representative Program Suite in Various Formats
Juice applets, other than by disabling either format counterparts in situ, without disrupting the ongoing
manually. program execution.
The Juice plug-in contains a dynamic code-generator that Periodic re-optimization of already executing code allows
translates from the slim binary representation into the to fine-tune the code-generator's output beyond the level
native code of the respective target architecture (PowerPC generally achievable by static compilation. Not only does it
or Intel 80x86). This translation occurs before the applet is enable run-time profiling data from the current execution
started, but is fast enough not to be noticed under normal to drive the next iteration of code optimization, but it also
circumstances. In contrast, most just-in-time compilers for makes it possible to cross-optimize application programs
Java translate individual methods as they are called rather and their dynamically loaded extensions and libraries. We
than the whole applet at once. Translating the whole are currently experimenting with global optimization
applet at once usually results in better code quality since it techniques that were pioneered by incremental compilers
permits inter-procedural optimizations to be exploited. and link-time optimizers. Among them are register
allocation and code inlining across module boundaries,
Due to the greater compactness of slim binaries in
global instruction scheduling, and global cache
comparison to Java byte-codes, less time has to be spent on
optimization. Run-time extensible systems present new
the transmission of Juice applets. The time saved can then
challenges to these old problems, since no closed analysis
be used to offset the cost of code generation. As the first
is possible due to the fact that further modules can be
author showed in his 1994 dissertation [4], using the slim
dynamically linked to the already executing system at any
binary representation can reduce I/O by so much that it
time.
fully compensates for the additional effort of code
generation. The dissertation originally concerned itself 5 A DIRECT COMPARISON OF JUICE AND JAVA
with object code read directly from a disk medium over a PROGRAMMING
fast bus; in the context of networks (which often have The easiest way of demonstrating the different "flavors" of
transfer rates far slower than secondary storage), this work programming in Juice vs. programming in Java is by
gains added significance. Further, the speed of processors presenting actual source texts. In Figure 3 we present, side
is rising faster than the speed of I/O, so that hardware by side, the source of a simple applet displaying the
technology is evolving in favor of increased density of current time in analog form (as shown in Figure 1),
code-representation formats. encoded using Java (left) and Juice (right). These sources
and the resulting executable applets can also be found on
The main thrust of our continuing research is focused on
our World Wide Web site.
improving code quality. Our implementations so far are all
based on a well-established family of compiler back-ends 6 CONCLUSION AND OUTLOOK
originating at ETH Zurich that produce high quality code Portable, executable content need not necessarily be tied to
comparable to that of straightforward commercial Java technology. In this paper, we have presented an
compilers [1]. On some newer RISC architectures, alternative to Java called Juice. Our implementation uses
however, these back-ends cannot fully compete with highly the existing plug-in mechanism of the major commercial
optimizing compilers. Of further concern to our particular World Wide Web browsers, demonstrating that the plug-in
application of load-time code generation is the fact that mechanism is suitable for supporting alternative mobile-
optimizers for certain RISC architectures may have vastly code solutions even in the case where on-the-fly code
different run-time characteristics than the compilers we generation is desired.
have been using so far.
Our implementation also shows that alternative mobile
Consequently, we are now pursuing a two-tier strategy of code solutions can remain completely transparent to end-
code generation. Rather than compiling every module users once that an appropriate plug-in has been installed.
exactly once when it is loaded and then leaving it alone, Hence, the eventual migration path from Java to a
we use a background process executing only during idle successor standard at the end of Java's life-cycle will
cycles that keeps compiling the already loaded modules probably be much less painful than most people anticipate
over and over. Since this is strictly a re-compilation of now.
already functioning modules, and since it occurs
In fact, the plug-in mechanism opens the door for
completely in the background, this process can be as slow
potentially many different Java alternatives that could be
as it needs to be, allowing the use of far more aggressive,
introduced over time, gradually reducing Java's pre-
albeit slower, optimization techniques than would be
eminence. Besides the Juice solution described here, a
tolerable in an "interactive" context. When background
strong initial candidate to win market share from Java
code-generation has completed, the code-images of the re-
might be Lucent's Inferno [9] (assuming that Inferno could
generated modules are substituted for their older
be packaged as a plug-in), but other contenders will surely [7] T. Lewis; "If Java is the Answer, What Was the
appear. Note that each plug-in itself can be distributed Question?"; IEEE Computer, 30:3, 136&133-135,
across the Internet, authenticated by a code-signing March 1997.
mechanism, simplifying the logistics of supporting several
[8] T. Lindholm, F. Yellin, B. Joy, and K. Walrath; The
competing code-formats concurrently.
Java Virtual Machine Specification; Addison-
It is also possible, and even probable, that the Java Wesley; 1996.
standard itself will fragment into several dialects. For
[9] Lucent Technologies Inc.; Inferno; http://plan9.bell-
example, Microsoft is incorporating an API into its version
labs.com/inferno/.
of Java and its Internet Explorer browser that differs from
the developments at Sun Microsystems, Java's original [10] M. Franz and T. Kistler; Juice; http:
creator. There may come a point at which the differences //www.ics.uci.edu/~juice.
between the various sets of libraries become irreconcilable,
[11] G. Muller, B. Moura, F. Bellard, Ch. Consel;
leading to mutually incompatible versions of Java. This
"Harissa: A Flexible and Efficient Java Environment
difference could be hidden from end-users using the same
Mixing Bytecode and Compiled Code"; Proceedings
approach that we have taken with Juice.
of the Third Conference on Object-Oriented
We believe that dynamic code generation technology is Technologies and Systems (COOTS), USENIX
reaching a level of maturity that it will soon diminish the Association Press, 1-20; 1997.
relative importance of "market share" of any particular
[12] K. V. Nori, U. Amman, K. Jensen, H. H. Nägeli and
code distribution format. In order to be commercially
Ch. Jacobi; Pascal-P Implementation Notes; in D.W.
successful, distribution formats will have to mimic Java in
Barron, editor; Pascal: The Language and its
providing architecture neutrality and safety, but further
Implementation; Wiley, Chichester; 1981.
considerations such as code density will surely gain in
importance. For example, some future distribution formats [13] Institut für Computersysteme, ETH Zurich, and
may be targeted towards particular application domains. In Department of Information and Computer Science,
this larger context, the current enthusiasm surrounding University of California at Irvine; Oberon Software
Java may soon appear to have been somewhat overblown. Distribution; http://www-cs.inf.ethz.ch/Oberon.html
or http://www.ics.uci. edu/~oberon.
REFERENCES
[1] M. Brandis, R. Crelier, M. Franz, and J. Templ; [14] T. A. Proebsting, G. Townsend, P. Bridges, J. H.
"The Oberon System Family"; Software-Practice and Hartman, T. Newsham, and S. A. Watterson; "Toba:
Experience, 25:12, 1331-1366; 1995. Java For Applications A Way Ahead of Time
(WAT) Compiler"; Proceedings of the Third
[2] M. Franz and T. Kistler; "Slim Binaries";
Conference on Object-Oriented Technologies and
Communications of the ACM, 40:12, to appear; also
Systems (COOTS), USENIX Association Press, 41-
available as Technical Report No. 96-24, Department
53; 1997.
of Information and Computer Science, University of
California, Irvine; 1996. [15] T. A. Welch; "A Technique for High-Performance
Data Compression"; IEEE Computer, 17:6, 8-19;
[3] M. Franz and S. Ludwig; "Portability Redefined"; in
1984.
Proceedings of the Second International Modula-2
Conference, Loughborough, England; 1991. [16] N. Wirth; "The Programming Language Oberon";
Software-Practice and Experience, 18:7, 671-690;
[4] M. Franz; Code-Generation On-the-Fly: A Key to
1988.
Portable Software; Doctoral Dissertation No. 10497,
ETH Zurich, simultaneously published by Verlag der
Fachvereine, Zürich, ISBN 3-7281-2115-0; 1994.
[5] M. Franz; "Technological Steps toward a Software
Component Industry"; in Programming Languages
and System Architectures, Springer Lecture Notes in
Computer Science, No. 782, 259-281; 1994.
[6] J. Gutknecht, "Oberon System 3: Vision of a Future
Software Technology"; SoftwareConcepts and
Tools, 15:1, 26-33, 1994.
import java.awt.*; MODULE JuiceClock;
import java.util.*;
IMPORT
public class JavaClock Math := JuiceMath, Applets := JuiceApplets,
extends java.applet.Applet Devices := JuiceDevices, Misc := JuiceMisc;
implements Runnable
{ TYPE
Applet = POINTER TO AppletDesc;
Thread timer = null; AppletDesc = RECORD (Applets.AppletDesc)
hour, min, sec: INTEGER
public void run() END;
{
while (timer!=null) { PROCEDURE Min(a, b: INTEGER): INTEGER;
repaint(); BEGIN
try {Thread.sleep(1000);} IF a < b THEN RETURN a ELSE RETURN b END
catch(InterruptedException e) {return;} END Min;
}
} PROCEDURE ArcLine(angle, x, y, r1, r2: INTEGER; dot: BOOLEAN);
VAR x1, y1, x2, y2: INTEGER; s,c,a : REAL;
public void start() BEGIN angle := (angle-15) MOD 60;
{ a := 2 * Math.pi / 60 * angle;
if (timer == null) { s := Math.Sin(a); c := Math.Cos(a);
timer = new Thread(this); x1 := SHORT(ENTIER(r1*c + 0.5));
timer.start(); y1 := SHORT(ENTIER(r1*s + 0.5));
} x2 := SHORT(ENTIER(r2*c + 0.5));
} y2 := SHORT(ENTIER(r2*s + 0.5));
Devices.Line(x+x1, y+y1, x+x2, y+y2);
public void stop() IF dot THEN Devices.FillOval(x+x2-5, y+y2-5, 10, 10) END
{ END ArcLine;
timer = null;
} PROCEDURE Update (me: Applet);
VAR r, r0, rs, rm, rh, x, y, i: INTEGER;
public int min(int a, int b) BEGIN Devices.Setup(me.device);
{ r := Min(me.device.w, me.device.h) DIV 2; r0 := 10*r DIV 11;
if (a < b) return a; rs := 8*r DIV 11; rm := 9*r DIV 11; rh := 7*r DIV 11; x := r; y := r;
else return b; Devices.SetForeColor(Devices.white);
} Devices.FillRect(0, 0, me.device.w, me.device.h);
Devices.SetForeColor(Devices.black);
public void arcline(Graphics g, int angle, int x, int y, int r1, int r2, boolean dot) Devices.FrameOval(0, 0, 2*r, 2*r);
{ i := 0; WHILE i < 60 DO ArcLine(i, x, y, r0, r, FALSE); INC(i, 5) END;
int x1, y1, x2, y2; double s, c, a;
Misc.GetTime(me.hour, me.min, me.sec);
angle = (angle - 15) % 60; ArcLine(me.min, x, y, 0, rm, FALSE);
a = 2*Math.PI / 60 * angle; ArcLine(me.hour * 5 + me.min DIV 12, x, y, 0, rh, FALSE);
s = Math.sin(a); c = Math.cos(a); Devices.SetForeColor(Devices.red);
x1 = (int)(r1*c + 0.5); ArcLine(me.sec, x, y, 0, rs, TRUE);
y1 = (int)(r1*s + 0.5); Devices.Restore(me.device)
x2 = (int)(r2*c + 0.5); END Update;
y2 = (int)(r2*s + 0.5);
g.drawLine(x+x1, y+y1, x+x2, y+y2); PROCEDURE AppletHandler (me: Applets.Applet; VAR M: Applets.AppletMsg);
if (dot) g.fillOval(x+x2-5, y+y2-5, 10, 10); VAR hour, min, sec: INTEGER;
} BEGIN
WITH me: Applet DO
public void paint(Graphics g) WITH M: Applets.DisplayMsg DO
{ IF M.id = Applets.update THEN Update(me)
int r, r0, rs, rm, rh, x, y, i; ELSE Applets.AppletHandler(me, M)
END
r = min(size().width, size().height) / 2; r0 = 10*r / 11; | M: Applets.IdleMsg DO Misc.GetTime(hour, min, sec);
rs = 8*r /11; rm = 9*r/11; rh = 7*r/11; x = r; y = r; IF (hour # me.hour) OR (min # me.min) OR (sec # me.sec) THEN
g.setColor(Color.white); Update(me)
g.fillRect(0, 0, size().width, size().height); END
g.setColor(Color.black); ELSE Applets.AppletHandler(me, M)
g.drawOval(0, 0, 2*r, 2*r); END
for (i=0; i