-
Notifications
You must be signed in to change notification settings - Fork 19
Improve JPMS support: linking native jars into the jlink image #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Add NativeModules
This doesn't sound like something that should be part of a plugin for JavaCPP. Wouldn't that be more appropriate in a more generic plugin for jlink like https://github.com/moditect/moditect-gradle-plugin ?
The problem with properties from custom classes like that is that I haven't found a way to let users set them from the command line. Am I missing something? |
From what I understand of how Gradle works, when inferModulePath isn't disabled, it should already be putting everything the module path, by default: https://docs.gradle.org/current/userguide/java_library_plugin.html Why isn't this happening? |
Ah, it looks like the badass plugin does its own inferencing instead of just using the module path from Gradle, see beryx/badass-jlink-plugin#198. I don't see the point of finding only the native modules related to JavaCPP when users probably just want to add all dependencies that they list anyway. Could you elaborate on the use case as to why this needs to be specific to JavaCPP modules instead of just taking everything from the module path? |
I haven't found either. But the
The module path does contain everything, it even contain too much (see below). The problem adressed by this PR is to
"Taking everything from the module path" is covered by the I agree that this PR doesn't bring a very satisfactory solution for people needing to link with Gradle. For instance, the way it selects the modules to add : from the runtime paths and looking for "system.arch" in their name, is not rigorous. |
Right, so, like I tried to explain before, Android is also too dumb to support native libraries bundled in JAR files, but we can easily compensate for that by extracting the libraries manually using Gradle, and spoon-feeding the extracted directory to its plugin. I've added documentation for that at the bottom of the README.md file, it's literally just 10 lines of code! But you know 10 lines of code is way too much code for the Android team to add to their plugin. What they want us to do is publish AAR files instead of JAR files. And now OpenJDK wants us to publish native modules in JMOD files instead of JAR files, so it's like what the hell is this crap? It triples the size of binaries uploaded to Maven Central, and it triples the time we have to maintain them. I'm not going to play that game! Why not just support JAR files, you know? They work just fine, OSGi has been supporting native libraries in JAR files for like forever, and it works just perfectly fine thank you! There's absolutely no reason to deal with this idiocy. Since neither Google nor Oracle is interested in making Java a sane platform when it comes to native binaries, we need to figure out something on our own. For starters, I'm sure we can come up with a hack very similar to the one for Android, but for jlink, so please do give it a try. If you are absolutely sure there is no way to deal with this in a sane way, then let's continue complaining at OpenJDK. It's their problem, also because Android depends OpenJDK. Maybe they will listen, eventually, but the chances of this happening are greater if we are able to show them that JAR files are sufficient and that we don't need JMOD files. |
In the meantime, what about generalizing your Android workaround and add some lines of code to this Gradle plugin that add the option of pre-extracting the native jars into the jlink images ? |
If you know a way to make this work, let's have a look at that, yes. That's what I said could help us convince people at OpenJDK to start doing the right thing. |
Here it is: #21 |
When running JPMS applications, JavaCPP users should only declare, in their module descriptor, the platform-independent module they need. For instance:
The platform-dependent native modules need to be added to the module graph with
--add-modules
command line argument when running the application, and when building an image with jlink.Since the module path is automatically populated with the needed native jars by Maven (using the
javacpp.platform
property)or by the Gradle plugin (using the
javacppPlatform
extra property),--add-modules ALL-MODULE-PATH
is enough for running the application.For building a JLink image with Maven, we can use the Apache Maven JLink plugin that automatically generates a
--add-modules
from the modules found in the module path.But with Gradle, we have nothing similar. If we use the JavaFX Gradle plugin or the Badass jlink plugin, there is no such auto-generated
--add-modules
and thus the native modules are not added to the image.If we configure Badass jlink plugin with
--add-module ALL-MODULE-PATH
, the image will contain all JavaCPP native modulesbut also all the standard modules from the JDK, ruining most of the interest of building a custom runtime with jlink.
This PR adds the computation of a native module list that can be used in the Badass JLink plugin configuration to generate a proper
--add-module
argument.It defines a javacpp extension to the platform plugin that contains the
plaforms
property and thenativeModules
property.The
nativeModules
property is computed during execution after theclasses
task (since it uses the runtime classpath, which can be modified during task execution), so must be added to the jlink task configuration in adoFirst
block.The
platforms
property replaces thejavacppPlatforms
extension property, but configuring the extra property is still supported for backward compatibility. Directly using theplatforms
property in ajavacpp
DSL block looks just a bit better.More configurations for the JavaCPP plugin could be added later in this extension.
Here is an example of build script with kotlin syntax:
Note that the JavaFX gradle plugin doesn't allow to configure
--add-modules
for jlink, and is not needed anyway to run or link applications using JavaFX.