Skip to main content

Support for the module keyword

Posted by mandychung on July 25, 2008 at 12:10 PM PDT

Very soon, in a week or two, the Java compiler (javac), packaging tool (jam), and the Java module system implementation in the OpenJDK Modules project will support the new module keyword (the language support for JSR 277).

The engineering team have built a special workaround to enable ourselves to build the Java module system while waiting for the language support. With the javac and jam tool support (thanks to Jonathan Gibbons and Kumar Srinivasan), you can now experience developing, building and packaging of a JAM module as JSR 277 spec defines.

The language support for JSR 277 consists of two parts: module membership and module accessibility. The module accessibility support requires both the javac and JVM support which will go in next (stay tuned!). This blog is to help you get started to build and play with JAM modules using the JDK built from the Modules project with the module membership support.

Module Membership Declaration

There are two different ways to use the module keyword to declare module membership:

1) To declare module membership in the individual source file of a class (recommended):

// hello/
module hello;
package hello;

public class HelloWorld {

2) To declare module membership in

// hello/
module hello;
package hello;

The module hello; declaration in a source file of a class applies the module membership to that particular class whereas the same module declaration in will apply the module membership to all classes in the "hello" package.

Compile a module

Since the module keyword is a new feature, you will need to run javac with -source 7 option:

$ javac -source 7 -target 7 hello/*.java

Module Compilation Unit

A file called is used to express the version, import dependency as well as other metadata about the module using annotations (java.module.annotation.*). Following the convention of, this could be stored in a directory corresponding to the module name.

This will be used by the jam tool to build a JAM module. For example, my hello.HelloWorld application depends on two libraries ( and that will be expressed in the file as follows:

// hello/
module hello;

The @MainClass annotation specifies the main entry point of the application.

You can download this sample aplication containing the hello,, and modules and try it out.

Package a JAM Module

The JDK provides a new JAM module packaging tool called "jam". To build the hello module:

$ jam cf hello.jam hello/module-info.class hello/HelloWorld.class

The jam command is similar to the jar command. The jam tool analyzes the list of input files and the module-info.class and generates the JAM module metadata (META-INF/MANIFEST.MF entry in the jam file). This metadata will be used by the Java Module System at runtime to enforce the versioning constraint and resolve the import dependency.

To build the other two JAM modules provided in the sample application,

$ jam cf com/foo/*.class
$ jam cf com/bar/*.class

Launch a Module Application

Once you build the JAM modules, you can run the module application as follows:

$ java -jam hello.jam

The -jam option is similar to the -jar option but launching a JAM module. Another way to launch the application:

$ java -repository . -module hello

The -repository option specifies the source location of the JAM modules and the -module option specifies the module name containing the main entry point.


There are few things you can try out:

  • Modify to access FooOrderImpl. It should fail. FooOrderImpl is a package-private class which is not exported in the module and thus is not accessible outside its own module.
  • Add a new isPaid() method in the interface. Modify the sample application to use the new version as follows:
    1. Modify to call the new Order.isPaid() method and print the value
    2. Modify to implement the new Order.isPaid() method
    3. Modify com/foo/ to a new version "2.0"
    4. Modify com/bar/ to a new version "2.0" and import with version="2.0+"
    5. Build the JAM files and

    Running java -jam hello.jam should continue to work with the new 2.0 version of those two libraries (i.e. printing out the value returned from the new isPaid() method).

  • Modify hello/ to specify the version of the imported modules as follows:

    // hello/
        @ImportModule(name="", version="1.0"),
        @ImportModule(name="", version="1.0")
    module hello;

    You can build a jam file called "hello-1.1.jam" and run it as:

    $ java -repository . -module hello:1.1

    This should use the 1.0 version of the OrderProcessingService and the PrintService.

Let us know what you think.

Feedback and Questions

Please send your feedback and questions to We are working to post a JDK binary built from the Modules project once the module membership change is integrated (stay tuned).

Related Topics >>