5

Quick background information for context: I'm writing a relatively small tool for a small gaming community to download and manage user generated content. It's a modular Java 24 + JavaFX Project done with Maven and IntelliJ.

I store data on a SQLite DB. So far I've used bare-metal JDBC and wrote queries myself. As the tool grows, I would like to simplify DB access. At work we use Hibernate ORM in a Jakarta EE environment with Jakarta Contexts and Dependency Injection (CDI) etc., but I've read you can use Hibernate without relying on dependency injection.

So I've tried Hibernate for my tool and it does work well in my dev environment. Problems arise when trying to package a build via jlink, specifically using the javafx-maven-plugin to make things a lot easier for me.

The downside is that Hibernate does not seem to be modularized. Meaning I cannot easily package it with jlink. Running mvn javafx:jlink reports the "automatic module cannot be used with jlink".

I've then tried EclipseLink as an alternative Jakarta Persistence (JPA) implementation, had no issues with automatic modules but other resources apparently not being properly packaged with jlink. Specifically some locale resources appeared to be missing when trying to launch the packaged app, so they got left out the final package.

The last resort would be trying some SQL-first libraries like jOOQ to at least make it more bearable than plain JDBC. But I'd really prefer a Jakarta Persistence/ORM approach to keep database handling as easy and painless as possible.

Does anyone have a working approach I can use for my case? Or share your setup that actually works for you? Or find a way to get any Jakarta Persistence implementation to work well with the module system and Maven/JLink? The reason I'm using these is that packaging really is as simple as invoking a single Maven goal and for the most part that worked really well. Especially because of that I'm hesitant to get into any other packaging method, like the other jlink Maven plugin or something like jpackage, which seem to be very tedious to configure and get working.

11
  • 2
    It seems a bit extreme to re-implement a working application just because Maven isn't applying the right steps for jlink / jpackage (both of which work fine with modular or non-module jars). Commented Nov 7 at 22:08
  • 3
    "some locale resources appeared to be missing when trying to launch the packaged app" -> jlink has options for handling locales, see include-locales. Commented Nov 7 at 22:21
  • 2
    @DuncG jlink can only work with non-automatic named modules (i.e., the module must have a module-info descriptor). But you're right about jpackage; that tool can work with non-modular code. Commented Nov 8 at 3:44
  • 3
    @jewelsea this singlehandedly solved the issue I had with the EclipseLink implementation re jlink. Thank you for this. Considering this is now a working solution within my constraints, I'll add this as the solution to my question (as soon as the question is re-opened) Commented Nov 8 at 12:57
  • 1
    @DuncG "ie It is still worthwhile using jlink" -- Just want to point out that jpackage always uses jlink when creating the application image, whether via --runtime-image for a preexisting runtime image or via arguments like --module-path, --add-modules, and --jlink-options for a runtime image it generates in the same invocation. Commented Nov 8 at 15:04

1 Answer 1

4

The remaining issue that prevented my jlink build was rather simple to solve, thanks to a crucial hint in the comments by jewelsea. So here is a more complete overview of a working scenario.

EclipseLink is a modular dependency that works well with jlink packaging through the javafx-maven-plugin. To satisfy dependency modules on jakarta.transaction, an additional dependency to jakarta.enterprise.cdi-api is needed in your Maven project, even if CDI is not used in the project itself.

Required modules in the module-info.java file would be:

  • jakarta.persistence
  • jakarta.transaction
  • org.eclipse.persistence.jpa
  • org.eclipse.persistence.core

include-locales

The last missing step is to let jlink include locales, so the necessary resources needed for EclipseLink are bundled with the application. For this, an option needs to be added to the javafx-maven-plugin:

<options> <option>--include-locales=en</option> </options> 

This way, there are no dependencies on automatic modules that jlink can't handle (like for example with hibernate) and the packaging and resulting runtime image works just fine.

Sign up to request clarification or add additional context in comments.

4 Comments

The jlink documentation for --include-locales, also says: "Ensure that you add the module jdk.localedata when using this option.", example --add-modules jdk.localedata --include-locales=en,ja,*-IN. If using the JavaFX Maven plugin you could either requires jdk.localedata in your module-info.java, or add it as an option to the plugin: <option>--add-modules jdk.locale.data</option>.
I'm not sure why exactly this is required, but thanks for the information. Specifically for my project it does not seem to be required, as in the final build runs without issue even without the module mentioned.
You are only including an English locale. What jdk.localedata does is provide "the locale data for locales other than US locale.". The US locale is, "en-US", so it includes English already. If you needed a different locale that didn't use English, then possibly your app would fail without the appropriate data from the jdk.localedata module.
@jewelsea At least in Java 25, jlink fails for me with "Error: jdk.localedata module was not specified with --add-modules option" if I pass --include-locales without ensuring the jdk.localedata module is resolved (even if I only include the "en-US" locale). I suspect that module is being resolved by other means for GenerationLost (perhaps indirectly required by one of the root modules) since they aren't getting that error. Or maybe the error was added in Java 25.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.