Skip to content

Commit f6b47e9

Browse files
committed
Add an option to use shading with the Maven plugin
1 parent a8e21d3 commit f6b47e9

File tree

4 files changed

+98
-9
lines changed

4 files changed

+98
-9
lines changed

docs/src/docs/asciidoc/maven-plugin.adoc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,24 @@ This step won't be needed as of JUnit 5.8 with a future release of native-maven-
147147

148148
Running `mvn -Pnative -Dskip test` will then build and run native tests.
149149

150+
== Long classpath and shading support
151+
152+
Under Windows, https://github.com/graalvm/native-build-tools/issues/85[it is possible that the length of the classpath exceeds what the operating system supports] when invoking the CLI to build a native image.
153+
154+
If this happens, one option is to use a https://maven.apache.org/plugins/maven-shade-plugin[shaded jar] and use it instead of individual jars on classpath.
155+
156+
First, you'll need to setup the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin]:
157+
158+
[source,xml,indent=0]
159+
include::../../../../samples/java-application/pom.xml[tag=shade-plugin]
160+
161+
Then the native plugin needs to be configured to use this jar instead of the full classpath:
162+
163+
[source,xml,indent=0]
164+
include::../../../../samples/java-application/pom.xml[tag=native-plugin]
165+
166+
Please refer to the https://maven.apache.org/plugins/maven-shade-plugin[Maven Shade plugin documentation] for more details on how to configure shading.
167+
150168
== Javadocs
151169

152170
In addition, you can consult the link:javadocs/native-maven-plugin/index.html[Javadocs of the plugin].

native-maven-plugin/src/functionalTest/groovy/org/graalvm/buildtools/maven/JavaApplicationFunctionalTest.groovy

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,15 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest {
5252
buildSucceeded
5353
outputContains "Hello, native!"
5454
}
55+
56+
def "can build and execute a native image with the Maven plugin and the shade plugin"() {
57+
withSample("java-application")
58+
59+
when:
60+
mvn '-Pshaded', '-DskipTests', 'package', 'exec:exec@native'
61+
62+
then:
63+
buildSucceeded
64+
outputContains "Hello, native!"
65+
}
5566
}

native-maven-plugin/src/main/java/org/graalvm/buildtools/maven/NativeBuildMojo.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
import java.nio.file.FileSystems;
6464
import java.nio.file.Files;
6565
import java.nio.file.Path;
66+
import java.nio.file.Paths;
6667
import java.util.ArrayList;
6768
import java.util.Arrays;
6869
import java.util.Collections;
@@ -94,7 +95,10 @@ public class NativeBuildMojo extends AbstractNativeMojo {
9495
@Parameter(defaultValue = "${mojoExecution}")
9596
private MojoExecution mojoExecution;
9697

97-
private final List<Path> classpath = new ArrayList<>();
98+
@Parameter(property = "classpath")
99+
private List<String> classpath;
100+
101+
private final List<Path> imageClasspath = new ArrayList<>();
98102

99103
private PluginParameterExpressionEvaluator evaluator;
100104

@@ -105,14 +109,18 @@ public void execute() throws MojoExecutionException {
105109
}
106110
evaluator = new PluginParameterExpressionEvaluator(session, mojoExecution);
107111

108-
classpath.clear();
109-
List<String> imageClasspathScopes = Arrays.asList(Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME);
110-
project.setArtifactFilter(artifact -> imageClasspathScopes.contains(artifact.getScope()));
111-
for (Artifact dependency : project.getArtifacts()) {
112-
addClasspath(dependency);
112+
imageClasspath.clear();
113+
if (classpath != null && !classpath.isEmpty()) {
114+
imageClasspath.addAll(classpath.stream().map(Paths::get).collect(Collectors.toList()));
115+
} else {
116+
List<String> imageClasspathScopes = Arrays.asList(Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME);
117+
project.setArtifactFilter(artifact -> imageClasspathScopes.contains(artifact.getScope()));
118+
for (Artifact dependency : project.getArtifacts()) {
119+
addClasspath(dependency);
120+
}
121+
addClasspath(project.getArtifact());
113122
}
114-
addClasspath(project.getArtifact());
115-
String classpathStr = classpath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator));
123+
String classpathStr = imageClasspath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator));
116124

117125
Path nativeImageExecutable = Utils.getNativeImage();
118126

@@ -170,7 +178,7 @@ private void addClasspath(Artifact artifact) throws MojoExecutionException {
170178
throw new MojoExecutionException("Artifact " + artifact + "cannot be added to image classpath", e);
171179
}
172180

173-
classpath.add(jarFilePath);
181+
imageClasspath.add(jarFilePath);
174182
}
175183

176184
private Path getWorkingDirectory() {

samples/java-application/pom.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,58 @@
9595
</plugins>
9696
</build>
9797
</profile>
98+
<profile>
99+
<id>shaded</id>
100+
<build>
101+
<plugins>
102+
<!-- tag::shade-plugin[] -->
103+
<plugin>
104+
<groupId>org.apache.maven.plugins</groupId>
105+
<artifactId>maven-shade-plugin</artifactId>
106+
<version>3.2.4</version>
107+
<executions>
108+
<execution>
109+
<phase>package</phase>
110+
<goals>
111+
<goal>shade</goal>
112+
</goals>
113+
<configuration>
114+
<shadedArtifactAttached>true</shadedArtifactAttached>
115+
</configuration>
116+
</execution>
117+
</executions>
118+
</plugin>
119+
<!-- end::shade-plugin[] -->
120+
121+
<!-- tag::native-plugin[] -->
122+
<plugin>
123+
<groupId>org.graalvm.buildtools</groupId>
124+
<artifactId>native-maven-plugin</artifactId>
125+
<version>${native.maven.plugin.version}</version>
126+
<executions>
127+
<execution>
128+
<id>build-native</id>
129+
<goals>
130+
<goal>build</goal>
131+
</goals>
132+
<phase>package</phase>
133+
</execution>
134+
</executions>
135+
<configuration>
136+
<skip>false</skip>
137+
<imageName>${imageName}</imageName>
138+
<buildArgs>
139+
<buildArg>--no-fallback</buildArg>
140+
</buildArgs>
141+
<classpath>
142+
<param>${project.build.directory}/${project.artifactId}-${project.version}-shaded.jar</param>
143+
</classpath>
144+
</configuration>
145+
</plugin>
146+
<!-- end::native-plugin[] -->
147+
</plugins>
148+
</build>
149+
</profile>
98150
</profiles>
99151

100152
<build>

0 commit comments

Comments
 (0)