Using legacy jar files with jlink
mark.reinhold at oracle.com
mark.reinhold at oracle.com
Thu Nov 16 23:35:45 UTC 2017
2017/11/16 15:03:37 -0800, Thomas Brand <tom at trellis.ch>:
> this is my first post here, I hope this is the right place to ask a
> question about how to use jlink.
Yes, it is!
> For a given scenario with modules a and b, a using methods of b, following
> instructions I managed to create a runnable image that can be called (from
> inside exploded image) like
>
> $ ./bin/java a.A
> A.main() called
> B() called
> string from B:test()
>
> this works nicely, also both modules are shown with
> $ ./bin/java --list-modules
> a
> b
> java.base at 10-internal
>
> My question is if it's possible to create that image if module b would be
> a legacy jar with just the .class files in it.
No. There's no place in the image to store arbitrary JAR files, and
even if there were there'd be no way to guarantee that all the other
JAR files required by those JAR files are present, since they're just
JAR files rather than modules. An image built by jlink is intended to
be complete, consistent, and runnable as-is rather than something that
might need additional JAR files just in order to launch.
> I understand it's possible
> to auto-generate the module-info.java for this legacy b.jar.
>
> I was thinking to be smart and just compile the generated module-info.java
> for b.jar and then put it to the legacy b.jar or put the module-info.class
> to the classpath in order to make it modular and then use for the jlink
> step.
> However that doesn't work:
>
> $JAVAC -d compile_out src/modb/module-info.java
> src/modb/module-info.java:2: error: package is empty or does not exist: b
> exports b;
> ^
> 1 error
To make this work, copy the content of b.jar into compile_out before you
run javac so that the compiler can detect that the package is not empty.
> How can a legacy jar file without access to source files be used as a
> module, is it possible at all? The idea is to use legacy jar files in
> conjunction with jlink to be used in self-contained runtime images.
It's possible, as above, but it can fail in many ways. If the legacy
JAR files contain conflicting packages then the module system won't be
able to load them. Your generated module-info.java files could have
missing dependences, especially if any of the legacy code uses
reflection.
It's really best to modularize an existing component properly, at the
source. If you can't do that, for whatever reason, then it's generally
safer to leave legacy JAR files on the class path. You can still use
jlink to generate a custom image containing just the modules that you
need; you'll just have to run that image with a non-empty class path.
- Mark
More information about the jigsaw-dev
mailing list