Project Jigsaw: Compiler Architecture Notes
2009/2/3
Requirements
See also "Requirements for modules in the Java language" for details of the implicit requirements for javac to support the module language features.
In addition to the language features, there are additional product requirements:
- javac must continue to function as now in conjunction with IDEs and other build systems, with minimal changes to the overall compilation pipeline.
- Source files must continue to compile to a classes/ directory.
- Classes compiled into the classes/ directory can immediately be used as input to subseqent compilations.
- It should be possible to use classes in modules without installing them in the system module library.
- It should be possible to compile against source and class files of modules that have been installed in the module library
- It should be possible to specify a policy to resolve which version of a module should be used, when more than one version is available (e.g. use oldest, use newest, use specific version)
- There should be command line option(s) to specify the module for compilation units that do not directly or indirectly contain a module declaration within the source language.
Files And Formats
- Module metadata written in the source language should appear in module-info.java, by analogy with package-info.java for packages.
- Classes using module source features will be written to version 51 class files.
- javac will read an optional new "modules directory", containing entries of the form module-name/module-version, each identifying a directory or jar file containing the class files for the specified module version.
Implementation Overview
Here is an overview of how this will be done inside the compiler.
The biggest change will be how javac accesses classes that are not provided on the command line. Almost all such access is currently handled via the JSR199 JavaFileMananager API, and so much of the work of interacting with the module system will be by means of a new or improved implementation of JavaFileManager.
Main
Option decoding: support any new options regarding the module system. Use of the module system will interact with existing path options and -source etc.ModuleFileManager
New subtype of JavaFileManager for interacting with the module system.Tree
New nodes will be required (at a minimum) for ModuleDeclaration and its contents. It may be desirable to clean up support for PackageDeclaration at the same time.Symbol
New class ModuleSymbol. PackageSymbols are currently global to the compilation and will likely become per-module.Scanner/Parser
Update for new ModuleDeclaration, and "module" as an access modifier. The primary aspect here is that we are using "restricted keywords" instead of full new keywords. For "module", we need two token lookahead to resolve potential ambiguities.Enter
This is where module declarations are handled; module metadata from module-info.java will be registered with the module system, through ModuleFileManager. ModuleSymbols and PackageSymbols get set up here, so that types declared in compilation units get declared in the correct context (i.e. module.)Check
This is where module accessibility is handled.ClassReader
ClassReader provides the high level to locate classes as well as to read .class files. It will likely have to be somewhat bimodal, providing a compatibility mode for current usage, and a new mode for accessing class dependencies from the module system, by means of ModuleFileManager.Lower
This is where we synthesize the package-info class from the info in the package-info.java file. The module-info class will be synthesized in a similar way.ClassWriter
ClassWriter will need to support the new module system attributes. This includes a "ModuleAttribute" on each type defined in a module, and the module metadata attributes for module-info.class files.Compatibility
javac is no longer "just" a compiler. It provides an API as well, and this API will have to be extended to accomodate the module system and the new language features.JSR 199
JSR 199 is the Compiler API. It provides JavaFileManager which is an SPI to allow the compiler to access the host file system. We will provide a new subtype, ModuleFileManager, that provides any additional access to the module system. One important aspect will be to temporarily register module metadata found in compilation units on the command line.JSR 269
JSR 269 is the annotation processing API. We will need to extend this API to reflect the new language features, such as ModuleDeclaration and the module access modifier.Tree API
The Tree API is a supported com.sun API providing access to the compiler's syntax tree. Originally intended for specialized clients such as NetBeans and other IDEs, it is becoming more widely used in other applications, such as the "checkers framework" extensions to JSR 308 (Annotations on Types.) Most of the changes will be to add new types, but there will be some additional changes to existing API as well.Miscellaneous
Although the primary delivery platform for javac is JDK, the source code is used in other products, such as NetBeans and the JavaFX compiler. As such, it is highly desirable that the code should degrade gracefully when run on earlier versions of the JRE. It is also a practical requirement for bootstrapping JDK that we can build and run javac on the previous FCS version of Java, i.e. Java 6. This will limit the use we can make of the new language features within javac itself. One possible solution is to limit the use of new features to selected source files (such as **/module-info.java, **/package-info.java, ModuleFileManager.java etc) which can safely be omitted to create a "bootstrap" version of javac.Related Tools
Other JDK tools, like javadoc and javap, provide -classpath and similar options. These tools will need to be upgraded to also provide access access to classes installed in the module system library. javadoc will also need minor upgrades to reflect the new language features- display the module in which a type is declared
- display the module access modifier
- display an index of the types defined in a module

