Closed knakul853 closed 4 years ago
mzmine is currently a non-modular application. Do you try to modularize it?
@knakul853 It's best if you push your current source code into a separate branch, including the build script and the new module-info.java. Then post a link to the branch here.
here is the link https://github.com/knakul853/mzmine3/tree/build
@knakul853 Thanks for the link! A lot of dependencies in this project have split packages, which leads to errors of the form: "module m reads package p from both m1 and m2". This means that it's not possible to modularize mzmine, unless you fix all these dependencies. That would require a huge amount of work and is probably not worth the effort, but if you still want to go this way, here are your options:
There is also the possibility to modularize the application only partially, by putting some dependencies on the module-path and some on the classpath. In this case, you need to continue using the badass-runtime plugin.
Personally, I would leave this application non-modularized.
@siordache Thanks for the explanation!
I thought the badass-jlink-plugin used the merged jar to combine the non-modular dependencies according to the description on the website:
The badass-jlink plugin takes a more pragmatic approach by combining all non-modular dependencies into a single jar. This way, only the resulting merged module needs a module descriptor.
Am I missing something here?
By the way, is there any way to use the jpackage tool when using the badass-runtime plugin?
The badass-jlink-plugin was not designed to help creating a modularized application. It assumes you already have it. (Otherwise, you need to use the badass-runtime-plugin.)
So, what does badass-jlink do? It allows you create a custom runtime image, even if your application has automatic modules (that is, non-modular dependencies). The jlink tool cannot work with automatic modules, so here is where the merged module comes into play. It is created only after your modular application has been compiled. From the point of view of your application's module descriptor, there is no such thing as a "merged module". The requires
clauses in the module descriptor reference only (proper or automatic) modules corresponding to your dependencies.
The badass-jlink-plugin doesn't help solving split packages issues. Instead, the gradle-modules-plugin provides support for patching modules to prevent split packages. This is an option that I somehow forgot to mention in my previous post. I have only limited experience with patching modules using the gradle-modules-plugin and I don't know how well the IDEs support this feature, but this is actually the most interesting option to consider.
The badass-runtime plugin also allows creating platform-specific installers via jpackage.
Thanks a lot! Now everything is clear.
@tomas-pluskal & @knakul853 I decided to try if patching the modules is a viable approach. The first problem is that currently the gradle-modules-plugin does not handle multiple jars. To overcome this issue, I created a custom variant of the gradle-modules-plugin that supports this feature. (It's just a quick-and-dirty fix, which is not compatible with Kotlin and also not conform with the proposed fix, so it doesn't qualify for a pull request.)
I also created a custom variant of the javafx-gradle-plugin that applies this modified gradle-modules-plugin. With this custom javafx-gradle-plugin and with a lot of patching and additional exports, the application builds successfully.
However, jlink is not able to create the runtime image, due to this bug, which will hopefully be fixed soon.
I submitted a pull request with my changes to the build
branch of @knakul853, so you can experiment with it. This PR should be regarded only as a proof-of-concept. For a proper solution we should wait until the gradle-modules-plugin adds supoort for patching multiple jars and a version of javafx-gradle-plugin applying it is released. Also, we need to wait until the above-mentioned jlink bug is fixed.
Hi @siordache Thanks a lot, that is a super helpful analysis! I think at the moment using the badass-runtime plugin is the best option for us. But for the future modularization is clearly the way to go.
@tomas-pluskal I totally agree with you.
I have been working on the mzmine build system and trying to use jlink. The issue I am facing is that when I try to import dependencies in the project it asks to add in the module descriptor even if it is nonmodular dependencies.for the sake of simplicity when I add (as IntelliJ suggest toPackage 'X' is declared in module 'Y', but module 'mymodule' does not read it ) this error goes but since package 'X' is in multiple modules so it throws an error. I am very new so it might be trivial but after stack and doc i am still not able to cope up with this problem i am getting short of this kind of errors link
here is my build script link