5

I am bundling an app using javapackager wherein the main jar is a module with a module-info.class but it relies on many other jars that are plain old jars, so I call them out as automatic modules in module-info.java. However, javapackager complains about not being able to find them. How do I make it find the jar files for automatic modules?

Exception: jdk.tools.jlink.plugin.PluginException: java.lang.module.FindException: Module rcf not found, required by com.username.commander.ui
Exception in thread "main" com.sun.javafx.tools.packager.PackagerException: Error: Bundler "Mac Application Image" (mac.app) failed to produce a bundle.
    at jdk.packager/com.sun.javafx.tools.packager.PackagerLib.generateNativeBundles(PackagerLib.java:374)
    at jdk.packager/com.sun.javafx.tools.packager.PackagerLib.generateDeploymentPackages(PackagerLib.java:348)
    at jdk.packager/com.sun.javafx.tools.packager.Main.main(Main.java:496)

I have tried specifying the module path (first dir has just the main module jar, second dir has all the non-module jars):

/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/javapackager -deploy -native image \
-name Commander -title Commander -vendor "username" \
--module-path /Users/username/Dropbox/coding/commander/Commander-java/moduleJars:/Users/username/Dropbox/coding/commander/Commander-java/packageJars \
--module com.username.commander.ui/com.username.commander.ui.AppWindow \
-srcdir /Users/username/Dropbox/coding/commander/Commander-java/packageJars \
-outdir /Users/username/Dropbox/coding/commander/Commander-java/target \
-outfile Commander \
-Bruntime=target/jre-9.0.1 -Bicon=src/main/resources/icons/commander.icns \
-BappVersion=1.0 \
-Bmac.CFBundleIdentifier=com.username.Commander \
--add-modules java.base,java.desktop,java.naming,java.sql,java.xml,java.logging,java.management,java.scripting,java.compiler,java.rmi,java.activation \
--limit-modules java.base,java.desktop,java.naming,java.sql,java.xml,java.logging,java.management,java.scripting,java.compiler,java.rmi,java.activation \
-nosign -v
Naman
  • 27,789
  • 26
  • 218
  • 353
GabeV
  • 859
  • 8
  • 21
  • Please update with the complete command used. Also, *each directory is a directory of modules.* is that true in your case? – Naman Oct 23 '17 at 04:49
  • Well, the 2nd directory has non-module jars, but that's part of my problem right? I'm trying to make it find automatic modules which are actually non-module jars in the strict sense. I know `-p` expects a directory of modules. Does that include automatic modules? – GabeV Oct 23 '17 at 05:17
  • Ideally, one would expect the automatic module to be a part of the module-graph without the need of you explicitly specifying it in the module-path args. Such that the modularJars would be having declarations that would include the automatic modules and add readability to them. – Naman Oct 23 '17 at 05:27
  • Yes I expected that as well. My main module jar has explicit `requires` statements for those necessary non-module jars, but `javapackager` is not finding them. – GabeV Oct 23 '17 at 05:32

2 Answers2

6

So after more research I've confirmed nullpointer's answer: automatic modules are simply not supported due to their access to the class path, which breaks the modularity of Java 9 modules. More details can be found in this discussion from about a year ago: http://mail.openjdk.java.net/pipermail/jigsaw-dev/2016-July/008559.html

So until Oracle and the Java community decide how to deal with this, javapackager in Java 9won't let you use automatic modules. If you bundle an app that uses a module, all your dependencies must be modules as well. If you require non-module dependencies, then you have to make all your jars non-modules. If you do make your jar(s) modular, then you have to make all your dependencies modular, which can be a lot of work or not possible if you don't own those dependencies.

If you make everything a non-module, the downside of course is that you don't get the advantage of a slimmer runtime that includes only the modules that you need. There is a workaround for this here.

GabeV
  • 859
  • 8
  • 21
  • Thanks GabeV. Just an addition: if one does not want to perform the suggested workaround, one can make even 3rd party jars modular by creating a suitable `module-info.java`, compile it and put it into the jar. You can then reference the jar as a regular module and `javapackager` will be happy. See https://stackoverflow.com/questions/47222226/how-to-inject-module-declaration-into-jar – CleanUp Jul 05 '18 at 17:45
  • Of course this is just another workaround, but depending your build automation setup, it might be easier to apply. – CleanUp Jul 05 '18 at 17:58
  • Yes that is a suitable workaround if you don’t have too many 3rd party library jars. – GabeV Jul 06 '18 at 22:07
2

Looking further the exception seems to be justified in its implementation over automatic modules, but the message seems to disguise as stated in the BUG#JDK-8189671.

It seems that a plugin reports that an automatic module being used as root because of missing module-info.class resource! jlink should detect attempt to use automatic module as root upfront and report error clearly.

Hence, you should be specifying the --module-path to the modularJars instead.

Additional Note: The Java packaging tools(javapackager) use the jlink tool to generate a custom JRE for the application.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • 3
    jlink has always rejected automatic modules. The recent bug fix that you linked to is just to improve the error. I suspect the issue is that javapackager isn't reporting the cause (from jlink) so the error is hidden. – Alan Bateman Oct 23 '17 at 06:47
  • 2
    @AlanBateman *exception seems to be just in its implementation over automatic modules, but the message seems to disguise*.. that's what I meant as well and for the same reason added the link to add details over hidden error. I think I would rephrase the word as *justified*, maybe that's causing confusion. – Naman Oct 23 '17 at 06:48
  • As I mentioned earlier, if I point to moduleJars for module path I get a different error. It complains that the jars in question are not module jars. It seems that you cannot put non-module jars in that directory. But then I’m back to my original problem: how do I make it find automatic modules? – GabeV Oct 23 '17 at 14:37
  • Are you saying that by design it’s not possible to use automatic modules or this is still a bug? The bug that was linked is fixed but won’t appear until Java 10. – GabeV Oct 23 '17 at 14:39
  • @GabeV Its by design that the automatic modules wouldn't be found by jlink(javapackager) and thats what I meant by justified. Also, the bug is more on towards the reporting of the tool. I cannot still seem to find a reason why automatic modules need to be explicitly specified while linking or packaging. You might want to add a reproducible project to the question in terms of what you're trying to achieve maybe. Also, does making use of `--add-modules ALL-MODULE-PATH` seem to help your use case? – Naman Oct 23 '17 at 15:02
  • 1
    You say that automatic modules need to be explicitly specified. My question is how to do that. Also when you say ALL-MODULE-PATH are you referring to my moduleJars path on my system or the actual keyword ALL-MODULE-PATH? – GabeV Oct 23 '17 at 16:05
  • @GabeV keyword... *automatic modules need to be explicitly specified* ...no, don't get me wrong, i mean I don't see why you want to explicitly specify them? – Naman Oct 23 '17 at 16:07
  • I will try the keyword. I didn’t think I needed to specify them because they’re supposedly automatic. However by default I get module not found so I was trying to see if specifying them helped. I’ll see if the keyword helps later. – GabeV Oct 23 '17 at 16:09
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157327/discussion-between-gabev-and-nullpointer). – GabeV Oct 24 '17 at 02:40
  • @GabeV the link to the chat discussion is a 404 now. Is there some record of the discussion somewhere, for those of us fighting similar problems? – Ti Strga Jun 14 '18 at 19:49