What is Jikes?
How do I use it? What options does it support?
Why must I define CLASSPATH
? What is JIKESPATH
?
How do I control the compiler listing?
What is incremental compilation?
How do I use Jikes to generate dependencies for make?
Why does Jikes reject a program that another compiler accepts, or accept one that it rejects?
What can I do if I don't get the same results when using class files generated by Jikes?
How do I report bugs?
Why did IBM Research make the source available?
What can I do with the source?
How do I compile the source?
How do I test the compiler?
Jikes is a compiler that translates Java source files as defined in The Java Language Specification into the bytecoded instruction set and binary format defined in The Java Virtual Machine Specification.
You may wonder why the world needs another Java compiler, considering that Sun provides javac free with its JDK. Jikes has four advantages that make it a valuable contribution to the Linux and Java communities:
jikes
++ myprog.java
This will compile myprog.java
and other files, as
needed, and leave Jikes running. You can then change myprog.java
or any of the source files it depends on. Then, you simply hit enter at
the command line to tell Jikes to re-check the dependencies and only
recompile files as required to bring the entire project up to date.
Jikes will stay in this "hit enter/rebuild" loop until you enter a
q
, which tells it to terminate.
The makefile generation feature is invoked with the +M
command-line option, as in: jikes +M myprog.java
.
This tells Jikes to perform full dependency checking on
myprog.java
and create a file that lists the
dependencies for each .class
file that will be created
by the compiler. By default this file has the same filename as the
source file, with an extension of u
. For example, the
dependency file for myprog.java
would be
myprog.u
.
It's worth pointing out that Jikes is not, and is not intended to
be, a complete development environment -- it is simply a command-line
compiler. It shouldn't be considered a replacement for more complete
tools, such as IBM's VisualAge for Java, which provides a
sophisticated graphical IDE (integrated development environment) and
offers the option of compiling Java to native binary code as well as
.class
files.
Increasingly, one of the easiest ways to get Jikes for Linux is with Linux itself -- Jikes is included in the Debian, FreeBSD, Mandrake-Linux, Red Hat, Linux PPC, and SuSE distributions.
The source code for Jikes is available under IBM's Public License, which has been approved by the OSI (Open Source Initiative) as a fully compliant open source license. The most recent stable release will be made available for download from the Jikes project homepage. CVS access to the most recent sources is also provided, the CVS info is as follows:
setenv CVSROOT :pserver:anoncvs@CVS.Sourcery.Org:/cvs/jikes
cvs login
(pasword is anoncvs)
cvs checkout jikes
The fact that Jikes is a high-performance, highly compatible Java compiler that can be used on almost any computing platform makes it an interesting program and worth investigating for almost any Java programmer. But Jikes is also notable because it lies at the center of two events: the adoption of open source philosophy and practice by large corporations, and the continued growth of Java for Linux.
In addition to the source code for the Jikes compiler, we also provide the source for JIKESPG, the parser generator used in part to build Jikes, and a test suite.
See Jikes News for news of recent developments.
See ports for a list of known ports--usually the work of an individual -- to other systems; some of the authors of these ports also provide binary versions.
Jikes users and developers communicate using the Jikes mailing lists.
The original version of Jikes, first released in binary form in April 1997, was written by Philippe Charles and Dave Shields of the IBM T. J. Watson Research Center. Since the release of the source in December 1998 they have continued work on the compiler as contributors.
Here are links to some of the articles in the press that have mentioned Jikes:
PC Week (December 1998):
Jikes! More open source code.
Javaworld (December 1998):
JavaWorld announces finalists in its 1998 Editor's Choice Awards.
Computing (April 1998):
Internet Java Tools Enrich the Bean Pool.
PC Week (December 1997):
PCW Labs' top 10 tech trends: It was the best of information technology.
PC Week (September 1997):
IBM spreading its software wings.
Infoworld (May 1997):
IBM to invest $100 million in Internet, networking research center this year.
Web Week (April 1997):
IBM Greases Java's Rails.
PC Week (April 1997):
IBM, Netscape Up Web Ante.
Invoke Jikes in the form:
jikes options filename...Invoke Jikes with no arguments to see a short summary of the arguments. Allowed options are:
-classpath path
-d dir
-debug
-depend
-deprecation
-g
LocalVariableTable
attribute.
-nowarn
-nowrite
-O
LineNumberTable
attribute.-verbose
-Xstdout
++
+B
-nowrite
generates byte code but does
not write it out.+CSO
class
or
java
file found. If CSO
is specified the Jikes behaves more like
javac
searching all directories for a class
or java
file,
and then comparing their dates to determine if a recompilation is necessary.
+D
+DR=filename
+E
+F
+M
+P
+Tnn
+U
+Z
Jikes can be used to compile more than one file at a time, causing a class file to be created for each Java source file. It is possible that compilation of a file named early on in the argument list will force the compilation of a file that is also named later on; however, no file will be compiled more than once. Jikes allows the same file to be named more than once; however, such files are only compiled once:
jikes Test.java x.java Test.java
Jikes also accepts arguments starting with an at-sign (@). Such arguments are taken be the name of a file, each line of which is then processed as though it were itself an argument, except that lines so read that begin with an at-sign are not processed recursively. For example, the above command could also be written as:
jikes @file.listwhere
file.list
is a file containing the lines:
Test.java x.java Test.java
CLASSPATH
? What is JIKESPATH
?
You must have some version of the JDK or JRE to run Jikes, so the
compiler can access the standard class files. Note that versions 1.1
of the JDK do not require that you provide a definition of
CLASSPATH
to run javac
and
java
. However, Jikes doesn't know what version of the
JDK you are using and so must be told how to find the standard
library files. This can be done in three ways:
CLASSPATH
; for example, in Win95 this takes the form
SET CLASSPATH=.;C:\JAVA\LIB\CLASSES.ZIPor for example, in Linux:
export CLASSPATH=.:/usr/local/jdk.1.1.6/lib/classes.zip (jdk) export CLASSPATH=.:/usr/local/jre1.1.6/lib/rt.jar (jre)
-classpath
option on the command line;
for example:
jikes -classpath .:$HOME/java/lib/classes.zip ...
JIKESPATH
as discussed below.
Jikes allows the use of JAR
files, which have the
standard "zip" format, provided that any contained class
files are stored either using no compression or the default
"DeflatedN" compression (also known as "method 8" in zip-speak).
Indeed, any item in the class path that is a not a directory is
assumed to be a file in zip format. The code used to do the the
uncompression is based on that used in unzip532
from
Info-ZIP, so we have to make the following statement:
Jikes incorporates compression code from the Info-ZIP group. There are no extra charges or costs due to the use of this code, and the original compression sources are freely available from Info-ZIP or Info-ZIP ftp site on the Internet.
Jikes looks for a definition of JIKESPATH
in the
environment before it looks for a definition of
CLASSPATH
. If JIKESPATH
is defined, then
its value is used when looking for a class file.
You should almost always include "." in the classpath; omit it only if you understand the implications.
The order in which the classpath is searched can also be selected using the
CSO
(Classpath Search Order) option. By default,
.java
or .class
file.
.java/.class
found in the leftmost classpath entry for
compilation purposes
If the CSO
option is specified, Jikes provides the same
behavior as javac
:
.java
file which occurs leftmost in the classpath.
.class
file which occurs leftmost in the classpath.
A caution is more severe than a warning,
but normally does not prevent the writing of the class file. The +Z
option can be used to prevent the writing of a class file if any cautions are detected.
A number of options select the kind and volume of the information
produced. They are -nowarn
, -verbose
,
+E
and +P
. The first two are found in most
Java compilers: -nowarn
requests that warning messages
not be written, -verbose
requests a report on the files,
including source and class files, read and written by the compiler.
The error kind option +E
is used to select how error
messages are formatted, By default, error messages are written in a
long form with the part of the text the compiler is complaining about
underlined, and with detailed explanatory text. The +E
option requests a terser form, suitable for automatic parsing by
editors such as
emacs
and
epsilon
. For example, consider the mis-typed "hello world" example:
class hello { public static void main(String[] args) { system.out.println("hi there"); // should be System... } }When
+E
is not used, the error is reported as
Found 1 semantic error compiling "hello.java": 3. system.out.println("hi there"); // should be System... <--------> *** Semantic Error: "system/out" is either a misplaced package name or a non-existent entity.With
+E
is used, the error is reported as:
hello.java:3:6:3:15: Semantic:"system/out" is either a misplaced package name or a non-existent entity.The initial part of each line contains several fields, separated by colons, giving in order the file name, the starting line in the file, the starting column in the starting line, the ending line, and the column number in the ending line.
The pedantic option +P
is used to request a
complete, pedantic listing. Just what is or is not pedantic
depends in part on e-mail we have received in which users have noted
that Jikes complains about constructs that other compilers accept.
(It is an open question whether the other compilers choose not to
report this information, or whether they do not even discover it.)
Select this option for a detailed listing. Currently, the following are only reported if +P
is selected:
This compilation unit contains no type declaration
An EmptyDeclaration is a deprecated feature that should not be used
private
access:
Note that the method ... in class ... does not override the corresponding method with private access in class ...
The method ... in class ... does not override the corresponding method with default access in class ...
The type associated with this construct is (or depends on) the type ... which is contained in an unnamed package
We say C
depends on D
if and only if the constant pool for C
contains a reference
to D
.
Types so referenced may need to be incorporated into the compilation, either by reading their class file or
compiling a source file
to produce the needed class file. Incorporation is done as follows:
-depend
option is to always compile a source file if there is one).
By default, Jikes does not incorporate D
unless it must.
If +F
is specified, and C
does not belong to a Zip or Jar file, the type D
is incorporated. Otherwise, D is
incorporated only if it must be.
If +U
is specified, then D
is always incorporated.
The option +F
directs the compiler to load all other
types that are referenced within a class file, and causes
recompilation of such files if their source file is more up-to-date
than the class file. Normally, other types are loaded only if
required for the current compilation.
The option -depend
(which can also be written
-Xdepend
, for 1.2 compatibility) directs the compiler to
always compile a source file, if one exists, instead of loading its
class file, even if it exists and is up-to-date.
Consider the following example:
// file A.java: class A { static public void main(String[] args) { System.out.println("enter A"); B.message(); } } // file B.java: class B { static void message() { System.out.println("enter B"); C.message(); } } // file C.java: class C { static void message() { System.out.println("enter C"); } }If no class files exist, then
jikes A.javaresults in compilation of
A
, B
and C
.
If C.java
(but not B.java
) is updated, then
jikes A.javaresults in compilation only of
A
. javac
does the same thing.
However, if C.java
(but not B.java
) is updated, then
jikes +F A.javaresults in compilation of
A
and C
.
It is always the case, independent of time-stamps of files, that
jikes -depend A.javaresults in compilation of
A
, B
and C
.
Note that
jikes -depend +F ...has the same effect as
jikes -depend ...i.e.,
+F
will cause no more files to be compiled than
will -depend
.
You can use +F
to get reports
of errors and warnings resulting from the use of out-of-date or
non-existent classes, at the expense of increasing compilation time.
By default, Jikes assumes that class files placed in Zip and Jar
files do not reference files not contained in Zip or Jar files; the
+U
option should be used when this is not the case.
Most Java compilers support at least some form of dependency
resolution, where we say that file A
depends on
file B
if a change to B
implies that
A
must be rebuilt. For example, A.class
depends on the source file defining A
, usually
A.java
. The make program is commonly used to
record the dependencies and keep files up to date.
Many Java
compilers support a simple make-like function, as follows: when
compiling A
check all classes referred to by
A
and recompile any whose class file is older than the
source file. This approach can cause problems if this implies
recompiling B
, and B is up to date, but uses
C
which is out of date, in which case C
may
not be recompiled.
Jikes supports the option -depend
and interprets it
as a request to recompile all used classes whether or not they are up
to date with respect to their source file.
Jikes also supports
the option +F
to force a fuller check of dependency. If
compilation of A.java
requires B.class
then
B
will be recompiled if it is out of date. Once
B.class
is available, it is read, and any classes it
references are also checked for dependencies. This fuller check is
more expensive, but will not cause the problems that can result using
the simple approach used by many compilers.
Jikes can also be run in an incremental mode that works as follows:
jikes ++ Main.javawhere
Main.java
denotes your root source file. Jikes
will then compile Main.java
and all the files it
references, building a complete set of dependencies, and will then
wait for input. (Note that ++
implies +F
also.)qin the window in which Jikes is waiting. Jikes will then terminate.
By the way, you may notice a substantial delay after you type
q
to end the incremental mode. This results from the
time needed to execute the destructors invoked to delete all the
nodes in the abstract syntax tree, all the symbols in the symbol
table, etc. This cost is also incurred whenever the compiler must
delete its current in-memory data structures before compiling a
changed file. We are aware of this cost and are looking at ways to
reduce it, but are making the compiler available with this known
performance limitation so you can try it and test it for correctness.
Most C
and C++
compilers support the
option -M
to generate dependency information for use
with make. Jikes provides the same function for Java using the option
+M
, which requests that Jikes create a file
X.u
for each file X.class
that is compiled,
and include in this file a list of all the files that
X.class
depends on. Note that use of the +M
option turns on full dependency checking (as is done by the
+F
option).
The contents of any zip files in CLASSPATH
are
assumed to be fixed, and so are not included in the generated
makefiles, mainly to avoid cluttering up the dependency list with
voluminous dependencies on the contents of java.*
.
You can also use the option +DR=filename
to request
that a dependence report be written to the file
filename
. The format is designed to allow the use of the
information as input to a tool; for example, it could be used for a
tool that determines the minimum set of class files that must be
included in a jar
file.
You may find that Jikes accepts a program that another compiler rejects (or can't compile), or rejects programs that another compiler accepts.
Each version of Jikes represents our best effort at the proper interpretation of the language specification. Although Jikes is designed to work with all but the earliest versions of the JDK, we make no claim that any particular version supports precisely the same language as any particular version of the JDK. Since some products are designed to work with specific versions of the JDK, the compilers associated with them may not always recognize the same programs as Jikes.
This section contains some examples of issues related to interpreting the specification.
Your program may contain extraneous semicolons that are silently ignored by many compilers. For example, given
public class Test { void f() {}; // first extra semicolon }; // second extra semicolonJikes accepts the program but issues:
2. void f() {}; // first extra semicolon *** Warning: An EmptyDeclaration is a deprecated feature that should not be used - ";" ignored 3. }; // second extra semicolon ^ *** Warning: An EmptyDeclaration is a deprecated feature that should not be used - ";" ignoredThe first extra semicolon is erroneous, the second is allowed by section 7.6. Jikes treats each as cause to issue a warning. You can use the
-nowarn
option to suppress this (and other) warnings, or, even better, you can use
your editor to delete those extra semicolons.
It is a compile-time error if a statement cannot be executed because it is unreachable (section 14.19). When Jikes first appeared, some other compilers didn't properly detect unreachable statements, and accepted programs such as the following:
class Test { void method(boolean b) { if (b) return; else return; b = !b; } }Jikes rejected this program:
b = !b; <-----> *** Semantic Error: This statement is unreachable(This is the example referrred to in PC Week (April 14, 1997): IBM, Netscape Up Web Ante)
Another example, and one that confused many users, is shown by the following program:
class Test { public static void main(String[] args){ try { } catch (Exception e) { System.out.println("caught"); } } }Jikes accepts this program but issues the warning:
catch (Exception e) { <---------> *** Caution: This catch block is unreachable: there is no exception whose type is assignable to "java/lang/Exception" that can be thrown during execution of the body of the try block
This was the most frequently reported problem when Jikes first appeared. It took several months to confirm that Jikes was right all along. See Query #2 to Sun for the full story.
Jikes rejects the program:
class X extends Y.Z {} class Y extends X.Z {}because Jikes checks for cycles by grouping types as follows:
Consider the following example:
class Z {} class W extends Z { class A { class x extends B {} class y extends x {} } class B { class x extends A.x {} } class C extends B.x {} }Its dependence graph contains the following edges:
W->Z
, since W
and Z
are both package membersW.A->W.B
, because type
W.A.x
extends W.B
W.A.y->W.A.x
, because type
W.A.y
extends W.A.x
W.B->W.A
, because type
W.B.x
extends W.A.x
W.C->W.B
, because type
W.C
extends W.B.x
This graph has a cycle: W.A->W.B->W.A
. So Jikes rejects
this program:
Found 3 semantic errors compiling "Z.java": 5. class A ^ *** Semantic Error: The class "W$A" is circularly defined with its super type(s) ...
Another example of cyclic dependence is found in the following code scheme used in some forms of the Swing package:
class C implements C.I { ... interface I { ... } }
This example is cyclic by Jikes's model of dependence. We asked Sun about this usage: Query #31 to Sun: Rules of inheritance of class members. Their response agrees with our interpretation that this usage is erroneous.
Here are some more examples of issues related to interpreting the language specification:
Query #1 to Sun: Inner Static
Query #2 to Sun: Unreachable Statements
Query #3 to Sun: Dependence
Query #4 to Sun: Are block-level inner interface declarations allowed?
Query #5 to Sun: String Concatenation Operator + and void
Query #6 to Sun: Getting a line on the LineNumberTable
Query #7 to Sun: Setting of InnerClasses_attribute inner_class_access_flags
Query #8 to Sun: Scope of Local Variable Declarations and Local Classes
Query #9 to Sun: Qualifying new for static inner class
Query #10 to Sun: Can a class access its own private methods via a subclass?
Query #11 to Sun: Access to members in anonymous classes
Query #12 to Sun: Anonymous inner classes should be final for instanceof and casts
Query #13 to Sun: Access to inner classes
Query #14 to Sun: Unreachability and do-while
Query #15 to Sun: Access control bug with protected member of sibling/outer classes
Query #16 to Sun: Floating point and bitwise operators
Query #17 to Sun: Compile-time evaluation of constant expressions
Query #18 to Sun: Explicit versus implicit setting of attributes, servialVersionUID algorithm
Query #19 to Sun: Octal escapes in string literals
Query #20 to Sun: What does "package-private method" mean?
Query #21 to Sun: Name resolution
Query #22 to Sun: Circularity problem?
Query #23 to Sun: Packages and non-existing directories
Query #24 to Sun: Protected
Query #25 to Sun: Can user-deifned package have a type named "java"?
Query #26 to Sun: Acceptability of unreachable byte code
Query #27 to Sun: Representation of null value
Query #28 to Sun: Use of anonymous class in explicit constructor invocation
Query #29 to Sun: When can the ConstantValue attribute be used?
Query #30 to Sun: Labeled statements and nested classes
Query #31 to Sun: Rules of inheritance of class members
Query #32 to Sun: Verification problem
Query #33 to Sun: Field resolution for interfaces
The Unofficial Java Spec Report is an unofficial site that covers problems with the Java Language Specification, the Java Virtual Machine Specification, and the core API documents. It is maintained by Roly Perera and Peter Bertelsen, and we wish to thank them for their service to the Java community.
Starting with Jikes v0.28, we will attempt to track the recommendations of the unofficial report, and implement them where feasible. The current status for the 1.1 portion in Issue 9 (22 May 1998) is as follows:
new
when qualified with an expression that evalutes to
null
is undefined -- Implemented.
new
or super
can be used unspecified --
Implemented.
this
be used in an explicit constructor invocation -- Implemented.
try
statements -- implemented.
It is possible that your current compiler was miscompiling the program and Jikes got it right. Jikes may have miscompiled your program and we would appreciate your reporting the problem. Here are some steps that may clarify the situation.
When you run your program using the Java virtual machine, run
java
with the option -verify
to enable
bytecode verification. If verification this shows one or more class
files are faulty, you've found a bug in Jikes. Please tell us about
it.
You should also to see if the Java virtual machine is using a JIT, in which case you should try with the JIT disabled. We have seen cases when JIT's fail with class files produced by Jikes, even though these class files pass verification.
Otherwise build two sets of class files, one using your current compiler and one using Jikes. Then, selectively substitute those produced by Jikes until you find a class file generated by Jikes whose use results in other than the expected output. If it appears that Jikes is at fault, please tell us about it.
Go to the Jikes bug page to report bugs.
You should provide a small program that reproduces the problem. If you do can not provide a test case, it in unlikely your bug will get fixed.
We do many things here at IBM Research, the most important of which is -- you guessed it -- research.
Work on what is now known as Jikes began in January 1996 when one of us (Philippe) decided to study the problem of compiling Java. The other (Dave) joined the project in April 1996, and started out by writing the bytecode generator. We have worked full-time on the compiler ever since.
We released Jikes in binary form in April 1997. During the spring of 1998 we received many requests for a Linux version. Jikes for Linux was released on 15 July 1998 -- the response was overwhelming. Jikes had more downloads in the three months after the announcement than in the fifteen months before the announcement. The increase in downloads was not just for the Linux version: there was a corresponding surge for the Win95/NT version. We also got many bug reports -- our main goal in putting out this version.
We knew that putting out a version for Linux would inevitably raise the question, "Where's the source?" We received many notes and comments from users suggesting why this would be a good idea, and prepared a Summary of User Comments. We found their comments persuasive, and began several months of work that resulted in the release of the source for Jikes in December 1998. This marked the start of one of IBM's first efforts in the open-source arena.
The source was released in part to make a very visible demonstration of IBM's commitment to open standards and to Java, to make Jikes more reliable and accessible, to encourage more widespread use of Java, to encourage standardization of Java, and to gain some experience actually running an open-source project.
Don't forget to read the license carefully. It explains in detail what you can and cannot do.
You can pretty much do whatever you want -- as long as we get some acknowledgment. You can distribute it in binary or source form, take all or part of it and put it in something else, and then redistribute it. It's all up to you.
However, IBM retains control of the names "IBM" and "JikesTM". You can't use them without our permission.
You are under no obligation to tell us what you are doing with the source, or to inform us of any changes you make.
./configure make
That should work, if it does not you may need to edit the soure code or the autoconf/automake build scripts. Gnu make is required to build jikes.
If you want to edit the Java parser rules in java.g, you will also need to download the Jikes Parser Generator in its source form, compile it, install it.
We rarely need to run the parser generator. The published Java
grammar is well-crafted; indeed, we don't recall having to make any
changes to make it acceptable as input to the parser generator. The
rare changes to java.g
are those needed to effect a
change in the action code.
Jikes is now using a new regression testing framework called Jacks. You will need to check this framework out of the CVS, use the same CVSROOT you used for jikes, the module name is jacks.
We are currently working on porting the old regression test suite over to the new Jacks framework. If you would like to help with this effort, please join the jikes-dev mailing list.