beryx / badass-jlink-plugin

Create a custom runtime image of your modular application
https://badass-jlink-plugin.beryx.org
Apache License 2.0
387 stars 27 forks source link

Missing main class attribute in manifest of jar generated by jlink #70

Closed daniel-odrinski closed 5 years ago

daniel-odrinski commented 5 years ago

Hi there, I am running into some issues with your plugin (awesome plugin btw), when I try to generate a JAR runtime image. I tried replicating the issue with one of the sample projects and am having the same issue there (the JavaFX sample application - modular).

When I import the project with Gradle and try to use the 'jlink' task, the jar is successfully created. However, upon trying to launch it through the command-line (since double-clicking fails), I am greeted by 'no main manifest attribute'. When I looked at the MANIFEST file, I could only see one line with the version, but the 'Main-Class' attribute from the 'application' plugin was nowhere to be seen. I've tried this with several projects now and I get the same result.

When I run 'jlinkZip', I get an image which works perfectly.

So I am kind of stumped as to why the 'Main-Class' attribute is not being injected into the manifest file inside the jar.

I am using macOS 10.14.5 with IntelliJ IDEA Ultimate.

Thanks in advance.

siordache commented 5 years ago

The jlink task creates an exploded custom runtime image in the build/image directory. It is not involved in the creation of the JAR file. The JAR file is generated by the jar task provided by the Java plugin. The jlink task just depends on the jar task. So, you can configure the 'Main-Class' attribute in the manifest file as usual:

jar {
  manifest {
    attributes ‘Main-Class’ : ‘org.example.MyApp’
  }
}

However, double-clicking the resulting JAR will most likely not work. You will need to launch the application through the command line, by also specifying the module-path.

You're trying to generate a "JAR runtime image", but this is a concept that doesn't quite make sense. It implies having a JRE inside the JAR file, but this JRE would be of little help, because you still need an external JRE in order to execute your JAR. What you probably really want is an easy way to distribute your application, preferably as a single, executable file. You have at least two options:

  1. Use the Shadow plugin to create a fat JAR. A JRE will still be required on your user's machine and the application will run as non-modular, with all artifacts on the classpath.

  2. Use the jpackage task to create a platform-specific application installer.

daniel-odrinski commented 5 years ago

Thank you for the very helpful explanation!

I am still learning how to distribute my applications and you have just clarified things for me. Thanks for making this awesome plugin!