oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources 🚀
https://www.graalvm.org
Other
20.36k stars 1.63k forks source link

Add support for Multi-Module java projects #7459

Closed SaptarshiSarkar12 closed 11 months ago

SaptarshiSarkar12 commented 1 year ago

Feature request

Is your feature request related to a problem? Please describe.

I am building a modular java project for Drifty. The source code for the project can be found here. I am using the Maven plugin of GraalVM to build native executables of the project. I have made three modules - Core, CLI and GUI for the project. When I try to build using GraalVM's maven plugin, it fails with the following error.

Build Error ```powershell [INFO] Scanning for projects... [INFO] ------------------------------------------------------------------------ [INFO] Reactor Build Order: [INFO] [INFO] Drifty [pom] [INFO] Core [jar] [INFO] CLI [jar] [INFO] GUI [jar] [INFO] [INFO] -------------------------< com.Drifty:Drifty >-------------------------- [INFO] Building Drifty 2.0.0 [1/4] [INFO] --------------------------------[ pom ]--------------------------------- [INFO] [INFO] --- native-maven-plugin:0.9.27:build (build) @ Drifty --- [WARNING] 'native:build' goal is deprecated. Use 'native:compile-no-fork' instead. [INFO] Found GraalVM installation from GRAALVM_HOME variable. [INFO] ------------------------------------------------------------------------ [INFO] Reactor Summary for Drifty 2.0.0: [INFO] [INFO] Drifty ............................................. FAILURE [ 0.063 s] [INFO] Core ............................................... SKIPPED [INFO] CLI ................................................ SKIPPED [INFO] GUI ................................................ SKIPPED [INFO] ------------------------------------------------------------------------ [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.534 s [INFO] Finished at: 2023-09-20T12:33:03+05:30 [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.27:build (build) on project Drifty: Image classpath is empty. Check if your classpath configuration is correct. -> [Help 1] [ERROR] [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch. [ERROR] Re-run Maven using the -X switch to enable full debug logging. [ERROR] [ERROR] For more information about the errors and possible solutions, please read the following articles: [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException ```
My Project structure
My CLI Module structure ![image](https://github.com/oracle/graal/assets/105960032/4529b941-2408-46d4-8ac1-3ac22c4eaf17)
My GUI Module structure ![image](https://github.com/oracle/graal/assets/105960032/87981f71-d1e9-4908-9409-192a609129e8)
My Core Module structure ![image](https://github.com/oracle/graal/assets/105960032/2c5426b6-f557-4c0d-8451-25b374fe5b78)
The pom files of my project
The parent pom file ```xml 4.0.0 com.Drifty Drifty 2.0.0 pom Core CLI GUI 20 20 UTF-8 5.10.0 1.0.21 0.9.27 GUI/Main.Drifty_GUI CLI/Main.Drifty_CLI 2.16.0 3.11.0 0.0.8 org.apache.maven.plugins maven-compiler-plugin ${maven-compiler-plugin} 20 20 org.codehaus.mojo versions-maven-plugin ${versions-maven-plugin} org.openjfx javafx-maven-plugin ${javafx-maven-plugin} ${guiMain} com.gluonhq gluonfx-maven-plugin ${gluonfx-maven-plugin.version} ${guiMain} ${system-linker-arg} --enable-url-protocols=https --enable-url-protocols=http --no-fallback --verbose -H:ResourceConfigurationFiles=${pom.basedir}/config/${resource-config-file} --add-exports=org.graalvm.nativeimage.builder/com.oracle.svm.core.jdk=ALL-UNNAMED --module-path=GUI/target/GUI-${project.version}.jar --module GUI --module-path=Core/target/Core-${project.version}.jar --module Core ${system-native-image-arg} ${guiMain} Drifty Drifty is an open-source interactive file downloader system ${package.type} ${project.version} ${project.version} true build-drifty-cli-for-windows-latest resource-config-windows.json org.graalvm.buildtools native-maven-plugin ${native-maven-plugin.version} true Drifty CLI ${cliMain} target/CLI/windows --enable-url-protocols=https --enable-url-protocols=http -H:ResourceConfigurationFiles=${pom.basedir}/config/${resource-config-file} --no-fallback -H:+ReportExceptionStackTraces --verbose build build package build-drifty-cli-for-ubuntu-latest resource-config-linux.json org.graalvm.buildtools native-maven-plugin ${native-maven-plugin.version} true Drifty CLI ${cliMain} target/CLI/linux --enable-url-protocols=https --enable-url-protocols=http -H:ResourceConfigurationFiles=${pom.basedir}/config/${resource-config-file} --no-fallback -H:+ReportExceptionStackTraces --verbose USE_NATIVE_IMAGE_JAVA_PLATFORM_MODULE_SYSTEM=true build build package build-drifty-cli-for-macos-latest resource-config-mac.json org.graalvm.buildtools native-maven-plugin ${native-maven-plugin.version} true Drifty CLI ${cliMain} target/CLI/macos --enable-url-protocols=https --enable-url-protocols=http -H:ResourceConfigurationFiles=${pom.basedir}/config/${resource-config-file} --no-fallback -H:+ReportExceptionStackTraces --verbose build build package build-drifty-gui-for-macos-latest pkg -Dsvm.platform=org.graalvm.nativeimage.Platform$MACOS_AMD64 ${pom.basedir}/config/missing_symbols-macos-latest.o resource-config-mac.json true build-drifty-gui-for-ubuntu-latest ${pom.basedir}/config/missing_symbols-ubuntu-latest.o resource-config-linux.json build-drifty-gui-for-windows-latest msi ${pom.basedir}/config/missing_symbols-windows-latest.o resource-config-windows.json ```
pom file of Core module ```xml 4.0.0 com.Drifty Drifty 2.0.0 Core 20 20 UTF-8 commons-io commons-io 2.13.0 org.hildan.fxgson fx-gson 5.0.0 com.google.code.gson gson 2.10.1 org.apache.commons commons-text 1.10.0 org.buildobjects jproc 2.8.2 ```
pom file of CLI module ```xml 4.0.0 com.Drifty Drifty 2.0.0 CLI 20 20 UTF-8 com.Drifty Core ${project.version} org.yaml snakeyaml 2.2 ```
pom file of GUI module ```xml 4.0.0 com.Drifty Drifty 2.0.0 GUI 20 20 UTF-8 20.0.2 com.Drifty Core ${project.version} org.openjfx javafx-controls ${javafx.version} ```

Describe the solution you'd like.

The main problem occurring now is that GraalVM can not detect if it is a multi-modular java project (at least I cannot find any option to tell GraalVM that it has multiple modules so it needs to handle in that way). So, it would be better if GraalVM could have this feature.

Describe who do you think will benefit the most.

GraalVM users will benefit the most. Since JDK 9, modularity has been introduced and most of the large Java apps are expected to make their project modular for independent code changes, efficiency and better security. So, this feature is going to really help those people like me.

Additional context

oubidar-Abderrahim commented 1 year ago

Hi, Thank you for your suggestion, I'm curious about what version of GraalVM you're using.

SaptarshiSarkar12 commented 1 year ago

@oubidar-Abderrahim I am using GraalVM 20.0.2+9.1. image

oubidar-Abderrahim commented 1 year ago

Hi, the version of GraalVM used is up-to-date so it should support building modular applications, could you please check our docs at https://www.graalvm.org/latest/reference-manual/native-image/guides/build-java-modules-into-native-executable/ and see if that helps.

SaptarshiSarkar12 commented 1 year ago

Hi @oubidar-Abderrahim :wave:! Thank you for responding. But, I am using the maven plugin of GraalVM for the build and it cannot recognize the multi-module structure of my project. I prefer using the maven plugin and it is being used in GitHub Actions CI/CD as well. I shall be glad if you can guide me to the right direction.

oubidar-Abderrahim commented 1 year ago

That shouldn't be an issue, you'll need to add the flags mentioned in our docs as buildArgs. you can check how on our plugin docs here: https://graalvm.github.io/native-build-tools/latest/maven-plugin.html

SaptarshiSarkar12 commented 1 year ago

@oubidar-Abderrahim Even after using the --module flag, it still throws error as shown below

[ERROR] Failed to execute goal org.graalvm.buildtools:native-maven-plugin:0.9.27:build (build) on project Drifty: Image classpath is empty. Check if your classpath configuration is correct. -> [Help 1]
SaptarshiSarkar12 commented 1 year ago

How should I solve it? I have added these (:point_down:) in the <buildArgs>

<buildArg>--module Core</buildArg>
<buildArg>--module CLI</buildArg>
oubidar-Abderrahim commented 1 year ago

Could you please share a small example of what you're trying to achieve and we can take a look into it

SaptarshiSarkar12 commented 1 year ago

@oubidar-Abderrahim I am planning to create three separate modules (two of which depend on the third) for my application Drifty. The parent pom is of Drifty's with three sub-modules - CLI, GUI and Core. The modules dependency can be visualised like this :point_down: Drifty Modules Visualised

I wish GraalVM to build the CLI application by building and using the source files of CLI and Core. Do you want to know anything else? I couldn't get what you meant by simple example. I just tried to make you understand what I wished to have.

SaptarshiSarkar12 commented 11 months ago

@oubidar-Abderrahim Is this feature being implemented? Have you understood the whole concept of my project, mentioned in the above comment?

oubidar-Abderrahim commented 11 months ago

Hi, this feature request doesn't make much sense because Native image does support modular java systems, you can find a simple example here: https://github.com/graalvm/graalvm-demos/tree/master/native-hello-module.

In case there is a bug, please create a bug-issue in our repository following our template, and provide a small reproducer code that we can build and verify the issue with.

Thank you

SaptarshiSarkar12 commented 11 months ago

@oubidar-Abderrahim But, How do I setup GraalVM for a project using more than one java module?

JaroslavTulach commented 2 weeks ago

I've been struggling with similar issue and this is my solution:

This is an example Maven configuration to invoke native-image binary directly via Maven exec:exec plugin and pass there all necessary JPMS arguments to build application composing of multiple modules: https://github.com/jtulach/NativeImageModularDemo/commit/f61ebfd677ec77e9c19104028bc0690b4cc376a2

SaptarshiSarkar12 commented 2 weeks ago

@JaroslavTulach Hi Jaroslav :wave:! Yes, this is the only working solution till now. Thank you for posting this soluton :smile:. It would help many people struggling to get GraalVM work with multi-module project. Now, it requires you to run mvn install before building "native-image" :upside_down_face:. I had already implemented this approach in https://github.com/SaptarshiSarkar12/Drifty/pull/398/commits/d990871536fa0dcb195a73081e5c48d5f17a137f commit in my project - Drifty. Forgot to post my solution back here :smiley:.