native-build-tools icon indicating copy to clipboard operation
native-build-tools copied to clipboard

334 - Fix module path and image classpath for native image generation

Open loiclefevre opened this issue 1 year ago • 9 comments

This PR should fix the issue related in #334.

This allows to simplify native image generation via Maven with such build args inside the pom.xml file:

                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>${native.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>build-native</id>
                                <goals>
                                    <goal>compile-no-fork</goal>
                                </goals>
                                <phase>package</phase>
                            </execution>
                            <execution>
                                <id>test-native</id>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                                <phase>test</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <verbose>true</verbose>
                            <skip>false</skip>
                            <imageName>${imageName}</imageName>
                            <fallback>false</fallback>
                            <agent>
                                <enabled>false</enabled>
                            </agent>
                            <buildArgs>
                                --module-path target/connectme-1.0.0.jar
                                -Ob
                                -march=native
                                --initialize-at-build-time=com.oracle.connect/com.oracle.connect.Main
                                --add-modules javafx.controls
                                --add-modules javafx.fxml
                                --add-modules com.oracle.connect
                                --module com.oracle.connect/com.oracle.connect.Main
                            </buildArgs>
                        </configuration>
                    </plugin>

The modification includes:

  • detecting properly if a dependency is a module (analyze jar file and look for the presence of /module-info.class
  • if it is a module, then populate --module-path arg list else populate -cp arg list

loiclefevre avatar Jun 20 '24 11:06 loiclefevre

This looks like a rather dangerous change to me. There are numerous examples of projects which simply break when things are added on the module path. Also this changes the classpath order, which can be a problem. At the bare minimum I would add a property to make this opt-in.

melix avatar Jun 20 '24 11:06 melix

This looks like a rather dangerous change to me. There are numerous examples of projects which simply break when things are added on the module path. Also this changes the classpath order, which can be a problem. At the bare minimum I would add a property to make this opt-in.

Would that help if this is enabled if and only if the main artifact (not the dependencies) appears to be a module?

loiclefevre avatar Jun 20 '24 11:06 loiclefevre

Ok, I've added a new plugin parameter: inferModulePath

                    <plugin>
                        <groupId>org.graalvm.buildtools</groupId>
                        <artifactId>native-maven-plugin</artifactId>
                        <version>${native.maven.plugin.version}</version>
                        <executions>
                            <execution>
                                <id>build-native</id>
                                <goals>
                                    <goal>compile-no-fork</goal>
                                </goals>
                                <phase>package</phase>
                            </execution>
                            <execution>
                                <id>test-native</id>
                                <goals>
                                    <goal>test</goal>
                                </goals>
                                <phase>test</phase>
                            </execution>
                        </executions>
                        <configuration>
                            <verbose>true</verbose>
                            <skip>false</skip>
                            <imageName>${imageName}</imageName>
                            <fallback>false</fallback>
                            <agent>
                                <enabled>false</enabled>
                            </agent>
                            <inferModulePath>true</inferModulePath>
                            <buildArgs>
                                --module-path target/connectme-1.0.0.jar
                                -Ob
                                -march=native
                                --initialize-at-build-time=com.oracle.connect/com.oracle.connect.Main
                                --add-modules javafx.controls
                                --add-modules javafx.fxml
                                --add-modules com.oracle.connect
                                --module com.oracle.connect/com.oracle.connect.Main
                            </buildArgs>
                        </configuration>
                    </plugin>

loiclefevre avatar Jun 20 '24 12:06 loiclefevre

In Native Image, we have:

Added ability to promote jars from the class-path to the module-path in the native image driver. Use ForceOnModulePath = ${module-name}. Promoting a module to the module-path is equivalent to specifying it on the module-path in combination with exporting the module using --add-modules ${module-name} to the unnamed module.

Is that something that could be used instead here?

fniephaus avatar Jun 21 '24 07:06 fniephaus

Sorry to say that's not solving the issue. Thanks

loiclefevre avatar Jun 23 '24 19:06 loiclefevre

That's ok, thanks for checking whether that mechanism could be used to solve your problem.

We've discussed this PR in the NBT meeting and the biggest obstacle seems to be that this is not easily reproducible on the Gradle side. And if we only support module inference in Maven, we introduce asymmetry in our plugins which we like to avoid as much as possible. The other concern is how useful module inference is in practice. Often, users seems to put modules on the class path because that's what they are used to. According to the Spring team, the demand for module support is still too low to be prioritized at this point.

Nonetheless, we'd like to continue this discussion. One alternative to the module inference approach would be a simple switch that puts the full class path on the module path. While that is potentially easier to implement, it's unclear whether a) this would solve your JavaFX and b) this would be useful for other use cases.

Let's keep this PR open until we have reached a consensus on how to proceed with module support in the NBT.

Again, thanks for your work so far! Much appreciated :)

fniephaus avatar Jun 26 '24 07:06 fniephaus

a simple switch that puts the full class path on the module path

That's basically what I did in https://github.com/jtulach/NativeImageModularDemo/commit/f61ebfd677ec77e9c19104028bc0690b4cc376a2#diff-abb4e0d98dcc6e2742e9b46d0f75f831b0e0dbe1feac6a85ebf38167130528a9:

I am using exec:exec Maven plugin to achieve this as I am not sure how to configure NBT to achieve the same. Simple switch <useModulePath>true</useModulePath> for doing similar change (e.g. using -p instead of -cp) might be good enough solution for a lot of users.

JaroslavTulach avatar Oct 22 '24 13:10 JaroslavTulach

@loiclefevre would @JaroslavTulach's proposal work for your JavaFX application?

fniephaus avatar Oct 22 '24 14:10 fniephaus

@loiclefevre is there a plan to progress with this? Have you tried suggestion from @JaroslavTulach if it works?

dnestoro avatar Mar 05 '25 11:03 dnestoro