How to add Java 9 module through manifest.mf?

My Java library must be compatible with Java 8 and Java 9. To work with Java 9, we need some of the Java 9 modules.

I know that I can add it via the command line using --add-modules . But this is a library, and I cannot manage the command line.

Is it possible to add this with manifest.mf ? Or is there another Java 8 compatible solution?

+8
java-9 jigsaw java-module
source share
3 answers

MANIFEST.MF has nothing to do with dependencies. You need to create a module-info.java file and declare your dependency there:

 module <module-name> { requires <dependency>; ... } 

However, if you compile module-info.java and just put module-info.class in the JAR, Java 8 will not be able to run it. So what to do? In Java 9: ​​multi-disk JAR files have a new feature ( JEP 238 ). The idea is that you can put Java 9 class files in a special directory ( META-INF/version/9/ ) and Java 9 will handle them correctly (while Java 8 ignores them).

So these are the steps you must follow:

  • Compile all classes except module-info.java using javac --release 8
  • Compile module-info.java using javac --release 9 .
  • Create a JAR file so that it has the following structure:
 JAR root - A.class - B.class - C.class ... - META-INF - versions - 9 - module-info.class 

As a result, the JAR must be compatible with Java 8 and Java 9.

UPDATE:

It turns out there is no need to insert module-info.class into the META-INF folder. You can just put it in the root of the JAR. This will have the same effect.

+6
source share

Modules express dependencies in their module declaration , so you need to create module-info.java , define the name of your module, dependencies (in your case with requires java.activation and requires java.xml.bind ) and export (more on this later).

The module declaration must be compiled by the Java 9 compiler to create the module descriptor module-info.class , which belongs to the root JAR folder.

Java 8 and 9

Java versions prior to 9 will ignore module-info.class , which means that if you compile the rest of your code for Java 8 (either using javac 8 or using the new --release flag on javac 9 ), your library is still functioning in this version.

Does your problem solve?

Even Java 9 only treats your JAR as a module if it ends in the path to the module . Only after that will he see the requires clauses and enable the Java EE modules that you use in the graph. This means that a client using your library along the path of the Java 9 class will still have to manually add two modules through the command line.

Full modulation

If your module is used in the path to the module accessibility rules , make sure that:

  • your clients can only use public types in the packages you export (at compilation and at runtime).
  • your code only sees the modules you depend on

It means:

  • you must specify the export in the module declaration
  • you must declare all dependencies, not just two JDK modules

In particular, the second point can be tough if you depend on projects that are not yet modular, but that is another matter. πŸ˜‰

+3
source share

Maybe in the last minutes of the puzzle there will be the necessary manifest parameters. Disadvantages, it will only work for the main jar file.

Example:

Add-Export: java.base / java.lang java.base / java.lang.invoke

or

Add-Exports-Private: java.base / java.lang java.base / java.lang.invoke

http://openjdk.java.net/projects/jigsaw/spec/issues/#AddExportsInManifest http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-September/000391.html

+3
source share

All Articles