1

since .jar is not anymore the best format to use to distribute our JavaFX project, I'm willing to use the tool JPackage for that instead, but after reading this post : https://stackoverflow.com/a/68823040/4262407, I ended up having multiple questions, but first of all, I just wanna make sure I ve well understood the process that I should follow :

the process :

1-create a modular project

2-package the project in a .jar format

3-use the tool Jlink to create a customized run-time image (to reduce the size of the output)

4-use the tool jpackage (it takes 2 and 3 as inputs)

I'm also wondering if I can rely on Intellij artifacts to create the .jar file (the 2 step) is it better to use a specific plugin ?

The last thing that is not clear is do we need to include the dependencies in the .jar file ? since I believe they will be included in the customized run time, won't they?

Youssef Idraiss
  • 396
  • 5
  • 19

4 Answers4

3

If you take a look here, there is an explanation on how to create JavaFX projects starting from a template that includes Maven plugins to easily pack the application using jlink.

Doing it like this will allow you to completely rely on IntelliJ, making things much easier.

Once you have your runtime image, you can pack it with jpackage. There was already a discussion about this topic here.

And here is a fast link to the article mentioned there. The article there shows it using Gradle, but you can do the same with Maven, just use the appropriate plugin (jpackage-maven-plugin, as stated in another answer here).

Also, from what I can read in your comments, it seems that you have both modular and non-modular dependencies. In that case, you can use jdeps to achieve what you need. There is a nice article here about having mixed dependencies, that specifically uses JavaFX as an example of modular library within a non-modular application.

  • Yeah you are right, it's easy to create a run-time image using maven, but what about jpackage ? also can i rely on Intellij artifacts to create the .jar file ? – Youssef Idraiss Aug 21 '21 at 10:28
  • You can use `jpackage` to pack the runtime image generated using `jlink`. I updated my answer with two links: one points to a previous discussion about using `jpackage` with `jlink`, the other is the article mentioned there, which explains how to do it. – flyingsquirrel01 Aug 22 '21 at 15:03
  • From other comments I saw that you are using a mix of modular dependencies and non-modular dependencies. I added a link in my answer to cover for that part as well with `jdeps`. Also, I forgot to mention this, but if you are using IntelliJ to generate a JavaFX project, you should know that for JDK 9+ the ant task is broken so you cannot rely on that, as it is documented in the [official jetbrains page](https://www.jetbrains.com/help/idea/packaging-javafx-applications.html#troubleshoot). – flyingsquirrel01 Aug 22 '21 at 15:19
2

Just have look here https://github.com/dlemmermann/JPackageScriptFX for a tutorial with a working example. Its especially useful for non-modular projects.

mipa
  • 10,369
  • 2
  • 16
  • 35
  • This may sound like a dump question but that tutorial is kind of confusing, should I use the scripts that the project provide or use the steps in README, because I use Jdeps using the commands in the tutorial " detected_modules=$JAVA_HOME/bin/jdeps --multi-release ${JAVA_VERSION} ..." and it's not allowed to use variables in windows CMD "detected_modules=" – Youssef Idraiss Aug 22 '21 at 09:03
2

I used the jpackage maven plug-in to build the native executable(https://search.maven.org/artifact/org.panteleyev/jpackage-maven-plugin). You will first have to use maven-javafx-plugin to create a jlink runtime image(https://github.com/openjfx/javafx-maven-plugin). You will then use that runtime image within jpackage plugin(... ).should create an executable successfully then.

Mensch
  • 21
  • 3
  • thank you for your answer, unfortunately using the jlink from maven isn't an option for me, since my project has a non-modular dependency :( – Youssef Idraiss Aug 22 '21 at 08:12
1

The jpackage tool does not require a modular project. Though if your project is not modular then your project will be mixed due to JavaFX being modular. In that case, you'll add the JavaFX modules to the custom run-time image while telling jpackage to treat your code as non-modular (i.e. it will configure the executable to place your code on the class-path).

You can also combine steps 3 and 4 into a single step. The jpackage tool can generate the custom run-time image. It will use jlink "behind the scenes".

As for what format your code needs to be in, packaging it in a JAR file will be, in my opinion, the most straightforward. But I'm not sure that's strictly required.

Any dependencies of your application will of course need to be included with the final application. If those dependencies are modular then you can have them included via the custom run-time image. But if you want them on the class-path then you can include them the same way as your code (i.e. --input).

Note the jpackage tool has a user guide: https://docs.oracle.com/en/java/javase/16/jpackage/packaging-overview.html

Slaw
  • 37,820
  • 8
  • 53
  • 80
  • in fact my project is modular but the problem is a used dependency "JasperReport" is not, I think that needs I should used jdeps, right ? – Youssef Idraiss Aug 22 '21 at 09:05
  • 1
    Named modules cannot reference members in the unnamed module, though code in the unnamed module can reference members in named modules. So if your code is modular then "JasperReport" is likely being turned into a so-called automatic module. In the past `jlink` could not work with automatic modules, but perhaps something has changed in more recent versions. If things haven't changed then yes, you'll have to convert "JasperReport" into an explicit module somehow. Or you could place your code on the class-path (i.e. unnamed module), while keeping JavaFX on the module-path (i.e. named modules). – Slaw Aug 23 '21 at 01:08