raydac / mvn-jlink

Maven plugin provides a way to load JDK and use its tools during project build
Apache License 2.0
43 stars 6 forks source link

Multiple Paths in --module-path not supported #1

Closed brcolow closed 5 years ago

brcolow commented 5 years ago

Hello,

I have two issues, actually.

1.) It seems that specifying more than one directory for --module-path is not supported. For example:

<modulePath>${jlink.jdk.path}${file.separator}jmods;target/</modulePath>

This is because in:

commandLineOptions.add("--module-path");
    if (this.modulePath != null) {
      log.debug("Detected non-empty module path in configuration: " + this.modulePath);

      final File modulePathFolder = new File(this.modulePath);

      if (!modulePathFolder.isDirectory()) {
        throw new MojoExecutionException("Can't find folder provided in 'modulePath': " + modulePathFolder.getAbsolutePath());
      }

It does not split the path on either : or ; (depending on if it's *nix or Windows) and check each element of the module path individually.

It would be nice if the plugin provided some property that is either ; or : depending on the OS running Maven (so that the POM is cross-platform) that could be used inside the module-path, but that's a secondary concern.

2.) Not sure if this is an issue with the plugin, but when trying to add the following option:

<option>--launcher bootstrap=com.dow.aws.lambda/com.dow.aws.lambda.Bootstrap</option>

I get the following error from jlink:

[ERROR] Error: unknown option: --launcher bootstrap=com.dow.aws.lambda/com.dow.aws.lambda.Bootstrap
Usage: jlink <options> --module-path <modulepath> --add-modules <module>[,<module>...]
Use --help for a list of possible options

It maybe could be because of the space?

Thanks very much for your useful plugin!

raydac commented 5 years ago

thank you very much for your report, I will investigate the first issue and what about the second one - try to split it as two option items

<options>
   <option>--launcher</option>
   <option>bootstrap=com.dow.aws.lambda/com.dow.aws.lambda.Bootstrap</option>
</options>
brcolow commented 5 years ago

That fixes the second issue. I thought Maven had an issue with spaces. Fixing the first should be relatively straight-forward (just need to split on the module-path separator which somewhat confusingly varies depending on if it's *nix or Windows). Thanks for your super quick response :).

raydac commented 5 years ago

I made changes and have replaced single string modulePath parameter by string list modulePaths, so you can try snapshot with such snippet

<modulePaths>
   <path>JDK.PROVIDER.JMODS</path>
   <path>target/</path>
</modulePaths>

path to the provider's jmods folder can be marked through pseudo-path JDK.PROVIDER.JMODS

brcolow commented 5 years ago

Thanks very much for your quick work on this. Is the snapshot available in a public repository?

raydac commented 5 years ago

I don't public snapshots in any repository, just clone project and build it locally, snapshot will be represented in your local maven repository

brcolow commented 5 years ago

Okay. For some reason it is stripping the module path:

<plugin>
 <groupId>com.igormaznitsa</groupId>
 <artifactId>mvn-jlink-wrapper</artifactId>
 <version>1.0.4-SNAPSHOT</version>
 <executions>
   <!-- Download AdoptOpenJDK for Linux, which we need to link against for a native Amazon Linux launcher. -->
   <execution>
     <id>cache-jdk11-linux</id>
     <goals>
       <goal>cache-jdk</goal>
     </goals>
     <configuration>
       <jdkPathProperty>jlink.jdk.path</jdkPathProperty>
       <jdkCachePath>${project.build.directory}/jdkCache</jdkCachePath>
       <provider>ADOPT</provider>
       <providerConfig>
         <os>linux</os>
         <release>jdk-12.0.2+10</release>
         <arch>x64</arch>
         <type>jdk</type>
         <impl>hotspot</impl>
       </providerConfig>
     </configuration>
   </execution>
   <!-- Run jlink (pointing it to the jmods of a Linux OpenJDK) to create the lambda bootstrap executable. -->
   <execution>
     <id>call-jlink</id>
     <goals>
       <goal>jlink</goal>
     </goals>
     <configuration>
       <output>${project.build.directory}/dist</output>
       <modulePaths>
         <path>JDK.PROVIDER.JMODS</path>
         <path>${project.build.directory}</path>
       </modulePaths>
       <addModules>
         <module>java.net.http</module>
         <module>com.dow.aws.lambda</module>
       </addModules>
       <options>
         <option>--launcher</option>
         <option>bootstrap=com.dow.aws.lambda/com.dow.aws.lambda.Bootstrap</option>
         <option>--compress=2</option>
         <option>--no-header-files</option>
         <option>--no-man-pages</option>
         <option>--strip-debug</option>
       </options>
     </configuration>
   </execution>
 </executions>
</plugin>

Result:

[INFO] --- mvn-jlink-wrapper:1.0.4-SNAPSHOT:jlink (call-jlink) @ project ---
[INFO] List of modules : java.net.http,com.dow.aws.lambda
[INFO] Formed module path: ;
[INFO] CLI arguments: --output C:\Users\brcolow\dev\dow\project\target\dist --launcher bootstrap=com.dow.aws.lambda/com.dow.aws.lambda.Bootstrap --compress=2 --no-header-files --no-man-pages --strip-debug --module-path ; --add-modules java.net.http,com.dow.aws.lambda
[ERROR] Error: Module com.dow.aws.lambda not found

Trying <path>./target</path> does the same thing.

raydac commented 5 years ago

yes, sorry there was some bug, try now

brcolow commented 5 years ago

It works :). Thanks a lot.

brcolow commented 5 years ago

One thing to note is that using JDK.PROVIDER.JMODS doesn't seem to be using the Linux JVM I specified in cache-jdk. I have to use ${jlink.jdk.path}${file.separator}jmods in order for it to use the correct one.

raydac commented 5 years ago

JDK.PROVIDER.JMODS uses path to jdk provider defined for jlink goal, if you use the pom which provided in the issue then your cache-jdk has downloaded one JDK and jlink uses default JDK which is same as maven uses. Usually cache-jdk is good if you make cross-platform java images, if you build for same host-os then you can avoid cache-jdk