Jar tool to transform a plain old JAR file to a modular JAR

Mandy Chung mandy.chung at oracle.com
Fri Apr 8 12:58:30 PDT 2011



This week I pushed the changeset to support modular JAR Files [1].
Below is a proposal to enhance the jar command-line tool to transform
a plain old JAR file into a modular JAR file by adding module metadata
to ease migration.  It's also posted at:
    http://cr.openjdk.java.net/~mchung/jigsaw/modular-jar-files.txt

Feedback, comments?

Proposal of jar tool enhancement
=======================
Modular JAR File

   A modular JAR file is a JAR file that contains a single module definition
   file (META-INF/module-info.class). It can be used as a JAR on the class
   path and installed as a module in a module library.

   o The META-INF directory
     * module-info.class

     The module-info.class file describes the module metadata.
     Grammar of the source file described in [2].

   o Signed JAR file
     A modular JAR can be signed in the same way as ordinary JAR.
     If a modular JAR file is signed, the META-INF/module-info.class
     entry must be signed to be installed in a modular library.

Tool to transform a plain old JAR file into a modular JAR

   The jar tool will provide the following new options for
   generating a module definition file in a jarfile:

     --module={module-name @ version}
         Generate META-INF/module-info.class entry in the JAR file.
         * jarfile name tends to be unnamed or contains '-' character.
           The module name will not be inferred from the jarfile name.
     --module-info-java={dir}
         Output module-info.java in the specified directory.

   The jar tool will also recognize if the inputfiles contains
   module-info.class (module-info.java and java files for the module
   are compiled in module compilation mode output to the same destination
   directory) and add module-info.class to the jarfile in the
   META-INF directory.

   Transform a jar file to a modular JAR
     jar uf jarfile --module=m.foo at 1.0

   You can also update the jarfile with an existing module-info.class:
     jar uf jarfile -C classes module-info.class

   Create a modular jar file
     jar c[v0M]f jarfile [-C dir] inputfiles --module=m.foo at 1.0
     jar c[v0]mf manifest jarfile [-C dir] inputfiles --module=m.foo at 1.0

   If module-info.class exists in the given inputfiles, it will
   create a META-INF/module-info.class entry:
     jar c[v0M]f jarfile module-info.class inputfiles

   The jar tool does not analyze the class dependencies of the jarfile.
   It will examine the manifest to infer the modules it requires and
   main-class for the modular JAR file as follows:
     If the "Main-Class" attribute is present in the manifest,
     it will use its value in the main entry point for the module.

     If the "Class-Path" attribute is present in the manifest,
     it will examine the list of jar files listed in the "Class-Path"
     attribute and check if they are modular JAR files and add them
     in its module dependency.

     If any of the jar files on the "Class-Path" attribute does not
     exist or not a modular JAR, it will output an error.

   jar tool allows unsigned entries be added to a signed jar file.
   If module-info.class is an unsigned entry in a signed jar,
   installation will fail. Therefore, transforming an existing signed
   jar to a modular jar file requires re-signing.  This is consistent
   with the existing behavior when the manifest is updated after it
   is signed that throws SecurityException at runtime.

   To modularize a set of existing jar files (one may depend on
   another specified in the "Class-Path" attribute), developers
   can run the jar tool on the existing jar files in an order
   of walking the dependency graph from the leaf node to the root,
   if possible, or have to create the module-info.java and compile
   it and add to each jar file.  The jar tool can provide an
   option to specify the module the jar file requiring:

     --require-module={module-name [version-query]}
         Specify the module it requires.  Multiple --require-module
         options can be specified.

   Rather than specifying the modules a jar file requires in a
   command-line, developers might just prefer to create the
   module-info.java and add to the jar.

   The proposal is to support the simple case first and check out
   existing libraries and applications to determine if the
   --require-module option is really helpful in practice in
   migrating them to modular jars.

Example Usage
   Modularize an existing JAR file
     $ jar uf astro.jar --module=org.astro at 2.0
     $ jar uf greetings.jar --module=com.greetings at 0.1
       - module dependency and main entry point are inferred
         from the manifest

   Specify a version range in the require-module option:
     $ jar uf greetings.jar --module=com.greetings at 0.1 --require-module="org.astro@<=2.0"

   Compile and package a modular JAR file
     $ javac -d modules -modulepath modules<java files>
     $ jar cf astro.jar -C modules/org.astro .
     $ jar cfm greetings.jar manifest -C modules/com.greetings .
       - module-info.class exists in the modules/com.greetigs
         and modules/org.astro directory

   Installing a modular JAR file in the module library
     $ jmod install greetings.jar astro.jar

   Launch the module installed above in module mode
     $ java -m com.greetings

   Launch a modular JAR file in legacy mode
     $ java -jar greetings.jar

References

[1] http://hg.openjdk.java.net/jigsaw/jigsaw/jdk/rev/0d838b758d8b
[2] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2011-March/001201.html





More information about the jigsaw-dev mailing list