4. Compilers and Tools

  • (Sect. 4) Is there a lex and yacc or preferably a flex and bison equivalent for Java?

    There is a lex equivalent called JavaLex and a yacc equivalent called CUP.

    LALR(1) parser JavaLex and JavaCup: http://www.cs.princeton.edu/~appel/modern/java/

    LL(k) parser JavaCC: http://www.metamata.com/JavaCC/
    LALR(1) parser SableCC from McGill U. http://www.sable.mcgill.ca/sablecc/index.html is generously made available under GNU license.

  • (Sect. 4) Where can I find a byte code obfuscator?

    Java Obfuscators replace the original class, field and methods names in the bytecode with meaningless strings. Second generation obfuscators are now appearing that also obfuscate the control flow and encrypt String literals. People use obfuscators on their applets if they want to hide their code from others. Generally, you wouldn't do this with software that you put on your website for others to enjoy. It runs counter to the "open source" philosophy of learning from other's code and allowing them to learn from yours.

    Zelix KlassMaster is a commercially supported obfuscator. It has a free evaluation version at http://www.zelix.com/klassmaster/
    Another commercially supported obfuscator, with a downloadable free trial is at http://www.4thpass.com/SourceGuard/. There are also some free works from students and others. http://www.primenet.com/~ej/

    Some people have reported problems using these with JDK 1.1.

    Obfuscators are intended to foil decompilers. Decompilers translate byte code back into Java source code. Mocha was the first and most well known of the decompilers; it's no longer supported. There is a decompiler (written in C++) at

    Because it is in C++, there are different versions for every architecture (hah!) There are also commercial products, such as SourceAgain from

    There's a very good Java Code Engineering and Reverse Engineering FAQ page at http://www.meurrens.org/ip-Links/Java/codeEngineering/.

  • (Sect. 4) Which program is used to create .zip files compatible with the java* programs?
    (e.g. classes.zip, moz3_0.zip)

    Use the jar-tool from JDK1.1(.1):

      jar [ options ] [manifest] destination input-file [input-files]


      jar cvf myJarFile.jar *.class

    creates a compressed archive. And watch out -- the order of the options ("cvf") determine the order of the arguments!

      jar cvfO myJarFile.zip *.class

    creates it fullsize (uncompressed) (note the 'O'-option used for JDK1.0.2)

    On Unix you can also use:

      zip -rn ".class" my_file.zip *

    Info-ZIP home page: http://www.cdrom.com/pub/infozip/
    Latest source code: ftp://ftp.uu.net/pub/archiving/zip/src/zip21.zip

    Netscape's command line version of its JAR packager and signing tool is called "zigbert". They also have a signing tool with GUI written in Java. More info http://developer.netscape.com/software/signedobj/jarpack.html

    If you zip your .class files for JDK 1.0.2 (for 1.1 you'll use a Jar):

    1. zip your files uncompressed (can use WinZip 6.2 up);
        Unix command:

        zip -r0 classes.zip <directories>

    2. Make sure the main class has no parent directory inside the archive, (in other words, don't build an archive with foo/bar/myMain.class, unless your myMain is in a package called foo.bar. Instead start it at myMain.class). Your packages must be placed in the archive using their corresponding filesystem pathnames.
    3. Put the archive in the same directory as the .html page.
    4. Put something like the following tag in the .html file:

      <APPLET CODEBASE="." ARCHIVE=my_zip_file.zip,myOtherZip.zip,thirdfile.zip CODE="my_main_class.class" WIDTH=600 HEIGHT=250> </APPLET>

    From JDK 1.1 on, an example of the applet tag used with a jar file is

    <APPLET ARCHIVE=myfile.jar CODE=myapplet.class WIDTH=600 HEIGHT=250> </APPLET>

    These lines will use an applet called myapplet that can be found in the jarfile myfile.jar. An example applet tag of a jar file used to hold classes in packages is

    <APPLET ARCHIVE="myclasses.jar" CODE="linden.net.MyApplet.class" WIDTH=480 HEIGHT=120> </APPLET>

    You can supply several jar filenames in a comma-separated list. Jar files are in compressed PKZIP format.

  • (Sect. 4) Can I compile a Java program to a binary executable, .exe on a PC?

    Compiling into native code destroys portability, which is one of the main benefits of Java. If you want to create a native executable because you wanted to make it easy to distribute and use programs, consider a Jar file instead.
    Some companies make products that do this. See the webpages for NaturalBridge http://www.naturalbridge.com , Symantec http://www.symantec.com, Supercede http://www.supercede.com/, and Tower Technology http://www.twr.com/. The first three are targeted to Microsoft Windows. Tower Technology supports several flavors of UNIXTM.

    Also, there is a native compiler from IBM, known as the HPJ (High Performance Java) compiler. One user has reported that it created a 2Mb executable from a 12K java file, and did not run any faster. See http://www.alphaworks.ibm.com/

    See also Instantiations JOVE http://www.instantiations.com/jove.htm,
    the paper about the Toba project http://research.microsoft.com/research/lt/toddpro/papers/coots97.pdf,
    Network World, "Vendors Rush To Speed Java Performance", Feb 9 1998, at http://www.nwfusion.com/news/0209java.html

    Compiling to native code takes away the most significant benefit of Java technology: portability of executables. Further, if you want your Java DLL (or .exe) to interact with C++, you'll have to specify which specific C++ compiler and/or actually compile some sort of linkage via the appropriate C++ compiler. C++ does not have a standard ABI, so there is a big problem with interoperability. Every C++ compiler uses a different object model, a different way of laying out class members, and a different way of "mangling" names for the linker.

    C is much simpler. The only question here is how structures are "packed" (i.e., are integers aligned on four-byte bounds?). All the C++ compilers can interact with C code, thanks to 'extern "C"' declarations.

    Consider carefully why you want to compile to a native executable, and whether there is a Java way to accomplish your goal. There may be a good reason for compiling to native code, but it needs to be thought through.

  • (Sect. 4) How can I performance profile my Java code?

    java -prof MyClass

    produces some basic output in a file called java.prof, showing the number of times methods were invoked. The output lines are of the form:
    # of calls method called called by time spent
    On a Unix system, you can sort the file with something like

    sort -r +82 <java.prof > java.sort

    More and better tools are a third party opportunity. One profiler is JProbe Profiler, available from http://www.klg.com/jprobe/. JProbe is said to be easy to use. Another profiler is OptimizeIt, available from http://www.optimizeit.com/. Each of these profilers has performance tuning, which shows which methods took how much time, and also memory tuning, which shows what objects are in memory and how they were allocated. Both are important things to know. The latest version of the CodeWarrior IDE http://www.metrowerks.com/ has a time-based profiler for Java code. Java WorkShopTM from Sun also has a time-based profiler.

    JDK 1.2 comes with some limited profiling capability built-in. Depending on your needs, it may be all that you need. Execute the following to get a short summary of what you can do:

    java -Xrunhprof:help

    For example, you can see which methods are taking the most time to execute, in the context of particular stack traces.

  • (Sect. 4) When I use javadoc and I click on any java class included in the JDK why do I get this message?

    Netscape is unable to find the file or directory named: /E|/Jwrkshop/JDK/bin/java.lang.Throwable.html

    References to the JDK classes assume that all generated html files are in the same directory and, in fact, that all files for all classes referenced are generated at the same time. There is no way to generate files incrementally and have them all reference each other, as you would like.

    As long as you have source for everything involved (including the JDK and all third-party classes), you can list all of your packages and all of the others on the javadoc command line and generate the whole set at once, but it is burdensome. Of course, if you receive any libraries as .class files, even this workaround will not suffice.

    Also javadoc will not generate the image files - you need to get them from the images directory under the JDK API documentation files. You can just copy the entire directory into your own doc directory. javadoc is a very nice concept, with a few implementation flaws.

  • (Sect. 4) I'm working on a project with lots of classes and I use the JDK. A recompile from scratch takes forever when I do it a class at a time. How do I recompile everything?

    The first way is

      javac *.java

    Another way is

      javac -depend tip.java

    where "tip.java" is a class "at the tip of the iceberg", i.e. that depends on (uses) all the other classes. Typically, this may be your main class. However, "-depend" is known to be buggy and cannot be relied upon. It also doesn't issue compile commands in parallel to make use of multi-processor systems.

    Without the "-depend" option, the standard "javac files" doesn't look beyond the immediately adjacent dependencies to find classes lower down the hierarchy where the source has changed.

    The -depend options searches recursively for depending classes and recompiles it. This option doesn't help when you have dynamically loaded classes whose names cannot be determined by the compiler from the dependency graph. E.g. you use something like


    The author of the code using those classes should make sure that those classes are mentioned in a Makefile.

  • (Sect. 4) Why do I get the java.lang.UnsatisfiedLinkError when I run my program containing Native Method invocations?

    Your program is not able to find your shared library or DLL.

    On Microsoft Windows 95/NT, make sure that the DLL exists in a path that is included within the PATH environment variable. (This need is true for both standard (untrusted) applications and trusted applets. At least, if you use the Java Plug-in to give yourself standard Java inside a browser).

    On Solaris, make sure that the environment variable LD_LIBRARY_PATH includes the path of your shared library.

    Note that jdb looks for libraries with "_g" appended to their names. Thus, if you intend to use jdb on an application that invokes native methods, you must ensure that the appropriately named libraries are in jdb's path. The "debug" nm libraries can simply be renamed copies of the nondebug libraries.

    For example, if your app invokes native methods in a library named mynm.dll (on Microsoft Windows) or mynm.so (on Solaris), make a copy in the same directory and name it mynm_g.dll or mynm_g.so.

  • (Sect. 4) An anonymous class can't seem to access a private outer method. Why is that?

    It's a known bug in the JDK 1.1.4. The code is:

    public class MyDialog { void Setup() { addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { myCloseWindow(); } } ); // anon inner class } private void myCloseWindow() { // private outer method dispose(); } }

    This code sends javac into an infinite loop. The workaround is to make the private method non-private, or to make the inner class a named class. Sun put a workaround in the compiler to silently set the field to package access.

  • (Sect. 4) What are the major releases and their contents?

    There have been three Java Development Kit releases from Sun so far, plus a number of bugfix (dot-dot) releases. The releases are:

    • JDK 1.0.2
      This was the release FCS in May 1996. It had some security fixes over JDK 1.0.
    • JDK 1.1
      This release (Feb 1997) introduced a new event model in the window system. It also made JDBC support and beans support a standard feature. It changed and standardized the native code interface to JNI. It also introduced inner classes.
    • JDK 1.2
      This release (Dec 1998) made the Swing library a standard feature. Swing is a set of rich platform-independent graphical components. It also introduced the Collections library, and Java 2D. JDK 1.2 was re-badged to JDK 2 at its launch.

  • (Sect. 4) What is the difference between jre and java?

    They are functionally equivalent, with minor differences in the handling of default classpath and options supported. To reduce confusion, the jre command was removed in JDK 1.2. Instead there is a "java" command in both bin and jre/bin.

    jre.exe is the java launcher that comes with the Java Runtime Environment. It ignores the CLASSPATH environment setting in favor of its own internally generated default and whatever is supplied on the cmd line using -cp or -classpath. It's intended to be a bit simpler for those who are only ever running programs, not developing them.

    java.exe is the launcher that comes with the JDK. It uses the CLASSPATH environment setting as a starting point and then tacks on its own internally generated entries.

    They both serve the same purpose and that's to start a Java VM, have it run a Java technology-based application, then terminate. The source for jre.exe is provided in the JDK. The source to java.exe is provided only in the JDK Source distribution.

  • (Sect. 4) What IDEs (Integrated Development Environments) are there?

    Some popular IDEs include:
    Apptivity (Progress) http://www.apptivity.com/
    Blue J (free) http://www.sd.monash.edu.au/bluej/
    Bluette (mostly free) http://www.bluette.com/
    Chicory (free) http://www.chicory.com/
    CodeGuide http://www.omnicore.com/
    CodeWarrior Professional http://www.metrowerks.com/
    Elixir http://www.elixirtech.com/ElixirIDE
    Freebuilder (free) http://www.freebuilder.org/
    GRASP (free) http://www.eng.auburn.edu/grasp/
    Grinder http://www.tpex.com/
    Java WorkShopTM (Sun) http://www.sun.com/workshop/java/
    Javelin, Visual Object Development for Java http://www.stepahead.com.au/
    JBuilder (free) http://www.inprise.com/jbuilder/
    JDE for emacs http://sunsite.auc.dk/jde/
    Jirvana (free) http://www.jirvana.com/Jirvana/Jirvana.html
    JPadPro http://www.modelworks.com/
    Kawa (Webcetera) http://www.tek-tools.com/kawa/
    Metamata http://www.metamata.com/
    NetBeans (Swing-based, written in Java, cross platform) http://www.netbeans.com/
    PARTS alpha (ObjectShare) http://www.objectshare.com/
    PowerJ (Sybase) http://www.sybase.com/products/powerj/
    SilverStream http://www.silverstream.com/
    Simplicity for Java http://www.datarepresentations.com/
    Super Mojo (Penumbra) http://www.penumbrasoftware.com/
    SuperCede (Asymetrix) http://www.supercede.com/
    teikade (PFU Ltd) http://www.pfu.co.jp/teikade/
    Together/J (Object Intl Inc.) http://www.oi.com/
    Visaj (Imperial SW Tech) http://www.imperial-software-tech.co.uk/
    VisualAge (IBM) http://www.software.ibm.com/ad/vajava/
    Visual Cafe (Symantec) http://cafe.symantec.com/
    Xelfi 0.94 http://www.xelfi.com/

  • (Sect. 4) What language is the compiler and JVM written in?

    • Sun's javac Java technology-enabled compiler is written in the Java programming language.
    • Sun's java JVM interpreter is written in the Java programming language with some C, C++ for platform-specific and low level routines.
    • Sun's Java Web ServerTM is written in the Java programming language.
    • Other companies have chosen other approaches. IBM's Jikes compiler (which is praised for its speed) is written in C++, but of course a version must be recompiled for each platform.

  • (Sect. 4) How do I turn off the JIT in the JDK?

    The command that works in both JDK 1.1.6 on, and JDK 1.2/2 is

    java -Djava.compiler=NONE ...

    One reason for turning off the JIT is to get more information about any exception that is thrown in your code. But HotSpot is able to produce line numbers in stack traces even for JIT'd code. HotSpot rocks.

  • (Sect. 4) How can I store the errors from the javac compiler in a DOS file?
    javac foo.java > errorfile doesn't work.

    javac writes errors to stderr, The problem is that DOS doesn't allow stderr to be redirected (as command.com is very poor software). So you have to use a special error redirection mechanism in the compiler:
    javac -J-Djavac.pipe.output=true myfile.java > errors.txt

    In JDK 1.2, you can use: javac -Xstdout
    You typically use this when a compilation produces a lot of error messages, and they scroll off the DOS window before you can read them.

    Alternatively, you can get a scollbar to appear on a DOS window by changing the properties with the "Layout" tab. Change the Screen Buffer Size Height: to some multiple > 1 of the Window Size Height. E.g. use a buffer height of 100 and screen height of 25 (the default). This will give you three buffers of scroll "history."
    The DOS limitation is improved in NT, where you can write
    javac myfile.java 2> errors.dat

  • (Sect. 4) How can I pretty-print Java source?

    For tools that reformat code, try:

    For tools that print code neatly, try:

    Some Unix utilities work adequately:

    • cb (very few style choices though)
    • alias printjava 'vgrind -lC++ -t -w \!* | lp' works pretty well too.
    Perhaps the best tools are the GNU utilities. Use enscript to generate postscript files with Java-specific formatting. Then use GhostScript/GhostView to preview and print the files to a non-PostScript printer, if necessary. The scripts can be found at: