Move JAR on Module Path (use legacy JAR as automatic module in JPMS project)

I want to modularize a Gradle 8.4 Java project with Java Platform Module System technology.
One of the dependencies of the project is itself an nonmodular JAR that I cannot change (let’s call it “old.jar”).
It seems that I have to “move old.jar on the module path” so it becomes an automatic module that can be used by a JPMS project.

In the Gradle 8.4 documentation I find this paragraph:

“While a real module cannot directly depend on the unnamed module (only by adding command line flags), automatic modules can also see the unnamed module. Thus, if you cannot avoid to rely on a library without module information, you can wrap that library in an automatic module as part of your project. How you do that is described in the next section.”

The phrase “you can wrap that library in an automatic module” seems to exactly address my problem. But I cannot find “the next section”.

Which is “the next section” in this context?

What is the recommended and future-proof way to use nonmodular legacy JARs in a modular (JPMS) Gradle 8.4 project?

It’s literally the next section the one starting in the following line, talking about artifact transforms.
But actually this is much simplified by using the GitHub - gradlex-org/extra-java-module-info: A Gradle 6.8+ plugin to use legacy Java libraries as Java Modules in a modular Java project which allows you to “patch” jars on the fly to make them modules if they are otherwise compatible with the module path, for example not have split packages.

1 Like

Thank you for the clarification!
Jendrik Johannes’ org.gradlex.extra-java-module-info plugin works great. This is something that could become part of Gradle, I find. I would not have found it without your help.

Imho it should not, it is a pretty dirty hack and can also easily lead to problems.
What indeed should be fixed is, that Gradle is too opinionated on what should go where when.
But for that there are already open issues.

OK, I see. Even though JPMS has been around for 6 years it does not seem to be very popular. To me it looks like a useful technology and I hope it will get full Gradle support.

Me too.
Well, it has “full” support, it is just not bug-free, also because of misunderstandings.
Afaik, it is not currently a focus for Gradle devs, but maybe a pull request improving it would be accepted. :wink:

Thanks for the feedback!

I have come to the conclusion that I need a Gradle multi-project to use JPMS. Each Java module corresponds to a Gradle sub-project. This looks OK for me, but can you confirm that this is the right approach?

The only difficulty I am aware of are nonmodular dependencies, where we will need the extra-java-module-info plugin.

What I don’t see in Gradle is access to and control over the “module path”. Dealing with a nonmodular dependency should (in theory…) be as simple as to “move it to the module path” (literally, move the JAR file to another directoy). If we had access to the module path as a variable in Gradle that would be doable. And further complications like split packages are “not Gradle’s problem”, I find. But my understanding is superficial and probably things are much more difficult in practice than they appear at first glance.

After several years of using Gradle I have not even realized that its sources are open and contribution is possible. Good to know!

Yes, as I said, manually saying “put this dependency on the module path” is one of the things that is missing and there is an open issue to track it.

You can do this manually with a bit of effort to manually construct the JVM args as you need them, or you can use the extra module info plugin to on-the-fly transform the non-modular jar to a modular jar or at least to an automatic module, so that Gradle automatically puts it to the module path.

1 Like