Compiling classes for multi-release JAR with module-info.java

Gunnar Morling gunnar at hibernate.org
Fri Feb 10 23:06:40 UTC 2017


Hi,

I'm trying to figure the intended process for compiling different
versions of a class for a multi-release (MR) JAR if there is a module
descriptor present.

I have these classes:

    --- src/main/java/com/example/Version.java
    package com.example;

    public class Version {

        private String value; String getValue() { return value; }
        public Version(String value) { this.value = value; }
    }
    ---

    --- src/main/java/com/example/A.java
    package com.example;

    public class A {
        public Version getVersion() { return new Version( "Java 8" ); }
    }
    ---

    --- src/main/java9/com/example/A.java
    package com.example;

    public class A {
        public Version getVersion() { return new Version( "Java 9" ); }
    }
    ---

I.e. "Version" is common to all Java versions supported by the MR JAR,
whereas there is one variant of "A" for Java 8 and one for Java 9.

If I don't have a module descriptor things work fine:

    javac --source-path=src/main/java -d target/classes --release 8
$(find src/main/java -name "*.java")
    javac --source-path=src/main/java9 -cp target/classes -d
target/classes-java9 --release 9 $(find src/main/java9 -name "*.java")
    jar --create --file mr.jar -C target/classes . --release 9 -C
target/classes-java9 .

Specifically, the second javac call picks up the (shared) class file
for "Version" from the classpath by pointing to the output directory
of the first compilation.

Things fail when adding a module descriptor:

    --- src/main/java9/module-info.java
        module com.example {
    }
    ---

Now the second javac call fails:

    src/main/java9/com/example/A.java:4: error: cannot find symbol
     public Version getVersion() { return new Version( "Java 9" ); }
               ^
     symbol:   class Version
     location: class A

It seems as if the presence of module-info.java suppresses the
configured classpath. Reading JEP 261 [1] I assumed this should be
supported: "It is possible to put arbitrary classes and JAR files on
the class path in [Single-module mode]", which I think is what I have
here.

Am I running into a bug? Or am I on the wrong track here and creating
such MR JAR should be done differently? If so, how should classes that
are meant to go into META-INF/versions/9 be compiled without
re-compiling all the shared classes?

Thanks for any pointers,

--Gunnar

[1] http://openjdk.java.net/jeps/261


More information about the jigsaw-dev mailing list