The JastAdd Extensible Java Compiler
The JastAdd Extensible Java Compiler provides both a proof-of-concept that JastAdd can be used for large substantial projects, lika a complete Java compiler. It also illustrates extensibility and modularity in showing how different tools and language extensions can be implemented as extensions to other components. The following paper described JastAddJ, the extensible Java compiler implemented in JastAdd:
T. Ekman, G. Hedin: The JastAdd Extensible Java Compiler. Proceedings of the 22nd Annual ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications (OOPSLA 2007), October 2007, Montreal, Canada.
Downloading
The latest version of JastAddJ can be accessed through the following subversion repository:
svn co http://svn.jastadd.org/projects/trunk/JastAddJ
You can also browse the latest version at http://svn.jastadd.org/projects/trunk/JastAddJ/
The source and pre-compiled binaries for release R20080423 are also available as jar archives:
- JastAddJ-src.jar - Source distribution of the compiler components
- Java1.4Checker.jar - Java 1.4 checker as executable jar
- Java1.4Compiler.jar - Java 1.4 compiler as executable jar
- Java1.5Checker.jar - Java 5 checker as executable jar
- Java1.5Compiler.jar - Java 5 compiler as executable jar
Compiler components
Java1.4Frontend
The Java1.4Frontend performs static-semantic checking including name analysis and type analysis and compile-time error checking. It is a high-quality implementation that passes almost all tests in the jacks test suite (more than javac and jikes).
A main program JavaPrettyPrinter is included that parses Java source code, performs static-semantic checking and prettyprints the programs to standard output.
Java1.4Backend
The Java1.4Backend is an extension of the Java1.4Frontend to form a full Java compiler, generating Java bytecode. The compiler is reasonably fast: around 3 times slower than javac.
A main program JavaCompiler is included that parses Java source code, performs static-semantic checking, and generates bytecode.
Java1.5Frontend
The Java1.5Frontend is an extension of the Java1.4Frontend and implements the language extensions in Java 1.5, including generics with wildcard support, the enhanced for statement, and static imports.
A main program JavaChecker is included that parses Java source code, and performs static-semantic checking.
Java1.5Backend
The Java1.5Backend is an extension of the Java1.4Frontend, Java1.4Backend, and Java1.5Frontend to form a full Java compiler, generating Java bytecode.
A main program JavaCompiler is included that parses Java source code, performs static-semantic checking, and generates bytecode.
Extended applications
Non-Null Types for Java
Non-null types is a type-based approach to detect possible null pointer violations in code statically at compile time. We have extended a Java compiler, in a modular way, to include non-null types. This is an example of how a large JastAdd project can be extended in an easy and declarative way. We have also implemented an inference algorithm to retrofit legacy code to include non-null types.
DevirtualizationAnalyzer
The DevirtualizationAnalyzer component is an extension of the Java1.4Frontend that implements a whole-program analysis of which method calls can be devirtualized. The implementation is in a very experimental stage, not yet taking all of Java's langauge constructs into account, but illustrates the ease with which advanced analyses can be built on top of the frontend.
Building
Unpack the source code:
> jar -xf JastAddJ-src.jar
The compiler components are unpacked to a folder named JastAddJ. Each component is a separate folder with its own build files that can be used to build the checkers and compilers. All tools needed to build the systems (jastadd2, jflex, beaver, etc.) are included. You only need to have javac and ant installed in order to continue.
To build the tools, make sure the components are in sibling directories. Then run
> ant
in each of the top directories. The components need to be in sibling directories since the Java 1.4 backend depends on the Java 1.4 frontend, and the Java 1.5 frontend depends on both the Java 1.4 frontend and backend. I you experience out-of-memory errors you have to increase the heap size for ant using the following command: ANT_OPTS="-Xmx256M" ant. If that works you may then want to create a file ~/.ant/ant.conf containing the following string: ANT_OPTS="$ANT_OPTS -Xms256M -Xmx256M". This will give ant more memory each time it is executed. There are some detailed comments on running JastAdd from within Eclipse here.
Run the Java 1.4 frontend:
go to the Java1.4Frontend directory
run the Java 1.4 static-semantics checking prettyprinter
> java JavaPrettyPrinter java-1.4-source-files
or see what options are available, e.g., for classpath
> java JavaPrettyPrinter -help
Run the Java 1.4 compiler:
go to the Java1.4Backend directory
run the Java 1.4 compiler
> java JavaCompiler java-1.4-source-files
or see what options are available, e.g., for classpath
> java JavaCompiler -help
Run the Java 1.5 frontend:
go to the Java1.5Frontend directory
run the Java 1.5 static-semantics checker
> java JavaChecker java-1.5-source-files
or see what options are available, e.g., for classpath
> java JavaChecker -help
Run the Java 1.5 compiler:
go to the Java1.5Backend directory
run the Java 1.5 compiler
> java JavaCompiler java-1.5-source-files
or see what options are available, e.g., for classpath
> java JavaCompiler -help