Skip to content

Commit e1999ff

Browse files
committed
Merge remote-tracking branch 'upstream/master' into dnestoro/fix-duplicated-junit-classpath-entries
2 parents 6f5eda2 + 424126c commit e1999ff

File tree

12 files changed

+297
-33
lines changed

12 files changed

+297
-33
lines changed

.sdkmanrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Enable auto-env through the sdkman_auto_env config
22
# Add key=value pairs of SDKs to use below
3-
java=22.2.r11-grl
3+
java=17.0.9-graalce

docs/src/docs/asciidoc/changelog.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ This version introduces a breaking change: the plugin now requires Gradle 8.3+ a
99

1010
- Added experimental support for layered images
1111

12+
=== Maven plugin
13+
14+
- Added support for running integration tests via maven-failsafe-plugin
15+
- Add `runtimeArgs` support to `native-maven-plugin`
16+
1217
== Release 0.10.6
1318

1419
=== Gradle plugin

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ The following configuration options are available:
119119
<propertyName>value</propertyName>
120120
</systemPropertyVariables>
121121
----
122+
`<runtimeArgs>`::
123+
To specify runtime arguments used for a native image run, use:
124+
[source,xml, role="multi-language-sample"]
125+
----
126+
<runtimeArgs>
127+
<runtimeArg>-XX:MissingRegistrationReportingMode=Warn</runtimeArg>
128+
</runtimeArgs>
129+
----
130+
131+
This parameter is only valid for the Maven Goal of `test`.
132+
122133
`<jvmArgs>`::
123134
To specify JVM arguments used for a native image build, use:
124135
[source,xml, role="multi-language-sample"]

native-maven-plugin/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,7 @@ tasks.withType<Checkstyle>().configureEach {
178178
// generated code
179179
exclude("**/RuntimeMetadata*")
180180
}
181+
182+
tasks {
183+
withType<Javadoc>().configureEach { options.encoding = "UTF-8" }
184+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package org.graalvm.buildtools.maven;
2+
3+
class IntegrationTest extends AbstractGraalVMMavenFunctionalTest {
4+
def "run integration tests with failsafe plugin"() {
5+
withSample("integration-test")
6+
7+
when:
8+
mvn '-Pnative', 'verify'
9+
10+
then:
11+
buildSucceeded
12+
file("target/failsafe-reports").exists()
13+
file("target/failsafe-reports/org.graalvm.demo.CalculatorTestIT.txt").readLines().any(line -> line.contains("Tests run: 6, Failures: 0, Errors: 0, Skipped: 0"))
14+
outputContains "[junit-platform-native] Running in 'test listener' mode"
15+
outputContains """
16+
[ 3 containers found ]
17+
[ 0 containers skipped ]
18+
[ 3 containers started ]
19+
[ 0 containers aborted ]
20+
[ 3 containers successful ]
21+
[ 0 containers failed ]
22+
[ 6 tests found ]
23+
[ 0 tests skipped ]
24+
[ 6 tests started ]
25+
[ 0 tests aborted ]
26+
[ 6 tests successful ]
27+
[ 0 tests failed ]
28+
""".trim()
29+
}
30+
}

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,10 @@
4141

4242
package org.graalvm.buildtools.maven
4343

44+
import org.graalvm.buildtools.utils.NativeImageUtils
4445
import spock.lang.IgnoreIf
4546
import spock.lang.Issue
47+
import spock.lang.Requires
4648

4749
class JavaApplicationWithTestsFunctionalTest extends AbstractGraalVMMavenFunctionalTest {
4850

@@ -182,4 +184,21 @@ class JavaApplicationWithTestsFunctionalTest extends AbstractGraalVMMavenFunctio
182184
outputDoesNotContain expectedOutput
183185
}
184186

187+
private static int getCurrentJDKVersion() {
188+
return NativeImageUtils.getMajorJDKVersion(GraalVMSupport.getGraalVMHomeVersionString())
189+
}
190+
191+
@Requires({ getCurrentJDKVersion() >= 23 })
192+
def "can use the Maven plugin with the runtimeArgs config to run tests in a native image"() {
193+
withSample("java-application-with-tests")
194+
195+
when:
196+
mvn '-Ptest-runtime-args', '-DquickBuild', 'test'
197+
198+
def expectedOutput = "Note: this run will print partial stack traces of the locations where a"
199+
200+
then:
201+
buildSucceeded
202+
outputContains expectedOutput
203+
}
185204
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ public abstract class AbstractNativeImageMojo extends AbstractNativeMojo {
168168
@Parameter(property = "jvmArgs")
169169
protected List<String> jvmArgs;
170170

171+
@Parameter(property = "runtimeArgs")
172+
protected List<String> runtimeArgs;
173+
171174
@Parameter(property = NATIVE_IMAGE_DRY_RUN, defaultValue = "false")
172175
protected boolean dryRun;
173176

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,16 @@ public void afterProjectsRead(MavenSession session) {
135135
}
136136

137137
// Test configuration
138-
withPlugin(build, "maven-surefire-plugin", surefirePlugin -> {
139-
configureJunitListener(surefirePlugin, testIdsDir);
140-
if (agent.isEnabled()) {
141-
List<String> agentOptions = agent.getAgentCommandLine();
142-
configureAgentForSurefire(surefirePlugin, buildAgentArgument(target, Context.test, agentOptions));
143-
}
144-
});
138+
List<String> plugins = List.of("maven-surefire-plugin", "maven-failsafe-plugin");
139+
for (String pluginName : plugins) {
140+
withPlugin(build, pluginName, plugin -> {
141+
configureJunitListener(plugin, testIdsDir);
142+
if (agent.isEnabled()) {
143+
List<String> agentOptions = agent.getAgentCommandLine();
144+
configureAgentForPlugin(plugin, buildAgentArgument(target, Context.test, agentOptions));
145+
}
146+
});
147+
}
145148

146149
// Main configuration
147150
if (agent.isEnabled()) {
@@ -202,8 +205,8 @@ private static void withPlugin(Build build, String artifactId, Consumer<? super
202205
.ifPresent(consumer);
203206
}
204207

205-
private static void configureAgentForSurefire(Plugin surefirePlugin, String agentArgument) {
206-
updatePluginConfiguration(surefirePlugin, (exec, configuration) -> {
208+
private static void configureAgentForPlugin(Plugin plugin, String agentArgument) {
209+
updatePluginConfiguration(plugin, (exec, configuration) -> {
207210
Xpp3Dom systemProperties = findOrAppend(configuration, "systemProperties");
208211
Xpp3Dom agent = findOrAppend(systemProperties, NATIVEIMAGE_IMAGECODE);
209212
agent.setValue("agent");

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

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
import java.util.HashSet;
7676
import java.util.List;
7777
import java.util.Objects;
78+
import java.util.Map;
7879
import java.util.Set;
7980
import java.util.function.Consumer;
8081
import java.util.stream.Collectors;
@@ -169,6 +170,9 @@ public void execute() throws MojoExecutionException {
169170
}
170171
systemProperties.put("junit.platform.listeners.uid.tracking.output.dir",
171172
NativeExtension.testIdsDirectory(outputDirectory.getAbsolutePath()));
173+
if (runtimeArgs == null) {
174+
runtimeArgs = new ArrayList<>();
175+
}
172176

173177
imageName = NATIVE_TESTS_EXE;
174178
mainClass = "org.graalvm.junit.platform.NativeImageJUnitLauncher";
@@ -178,32 +182,36 @@ public void execute() throws MojoExecutionException {
178182
}
179183

180184
private void configureEnvironment() {
181-
// inherit from surefire mojo
182-
Plugin plugin = project.getPlugin("org.apache.maven.plugins:maven-surefire-plugin");
183-
if (plugin != null) {
185+
List<Plugin> plugins = new ArrayList<>();
186+
187+
Plugin surefire = project.getPlugin("org.apache.maven.plugins:maven-surefire-plugin");
188+
if (surefire != null) {
189+
plugins.add(surefire);
190+
}
191+
192+
Plugin failsafe = project.getPlugin("org.apache.maven.plugins:maven-failsafe-plugin");
193+
if (failsafe != null) {
194+
plugins.add(failsafe);
195+
}
196+
197+
for (Plugin plugin : plugins) {
184198
Object configuration = plugin.getConfiguration();
185199
if (configuration instanceof Xpp3Dom) {
186200
Xpp3Dom dom = (Xpp3Dom) configuration;
187-
Xpp3Dom environmentVariables = dom.getChild("environmentVariables");
188-
if (environmentVariables != null) {
189-
Xpp3Dom[] children = environmentVariables.getChildren();
190-
if (environment == null) {
191-
environment = new HashMap<>(children.length);
192-
}
193-
for (Xpp3Dom child : children) {
194-
environment.put(child.getName(), child.getValue());
195-
}
196-
}
197-
Xpp3Dom systemProps = dom.getChild("systemPropertyVariables");
198-
if (systemProps != null) {
199-
Xpp3Dom[] children = systemProps.getChildren();
200-
if (systemProperties == null) {
201-
systemProperties = new HashMap<>(children.length);
202-
}
203-
for (Xpp3Dom child : children) {
204-
systemProperties.put(child.getName(), child.getValue());
205-
}
206-
}
201+
applyPluginProperties(dom.getChild("environmentVariables"), environment);
202+
applyPluginProperties(dom.getChild("systemPropertyVariables"), systemProperties);
203+
}
204+
}
205+
}
206+
207+
private void applyPluginProperties(Xpp3Dom pluginProperty, Map<String, String> values) {
208+
if (pluginProperty != null) {
209+
Xpp3Dom[] children = pluginProperty.getChildren();
210+
if (values == null) {
211+
values = new HashMap<>(children.length);
212+
}
213+
for (Xpp3Dom child : children) {
214+
values.put(child.getName(), child.getValue());
207215
}
208216
}
209217
}
@@ -235,6 +243,7 @@ private void runNativeTests(Path executable) throws MojoExecutionException {
235243
command.add("--xml-output-dir");
236244
command.add(xmlLocation.toString());
237245
systemProperties.forEach((key, value) -> command.add("-D" + key + "=" + value));
246+
command.addAll(runtimeArgs);
238247

239248
processBuilder.command().addAll(command);
240249
processBuilder.environment().putAll(environment);

samples/integration-test/pom.xml

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
4+
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
6+
The Universal Permissive License (UPL), Version 1.0
7+
8+
Subject to the condition set forth below, permission is hereby granted to any
9+
person obtaining a copy of this software, associated documentation and/or
10+
data (collectively the "Software"), free of charge and under any and all
11+
copyright rights in the Software, and any and all patent rights owned or
12+
freely licensable by each licensor hereunder covering either (i) the
13+
unmodified Software as contributed to or provided by such licensor, or (ii)
14+
the Larger Works (as defined below), to deal in both
15+
16+
(a) the Software, and
17+
18+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
19+
one is included with the Software each a "Larger Work" to which the Software
20+
is contributed by such licensors),
21+
22+
without restriction, including without limitation the rights to copy, create
23+
derivative works of, display, perform, and distribute the Software and make,
24+
use, sell, offer for sale, import, export, have made, and have sold the
25+
Software and the Larger Work(s), and to sublicense the foregoing rights on
26+
either these or other terms.
27+
28+
This license is subject to the following condition:
29+
30+
The above copyright notice and either this complete permission notice or at a
31+
minimum a reference to the UPL must be included in all copies or substantial
32+
portions of the Software.
33+
34+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40+
SOFTWARE.
41+
-->
42+
43+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
44+
http://maven.apache.org/xsd/maven-4.0.0.xsd">
45+
<modelVersion>4.0.0</modelVersion>
46+
47+
<groupId>org.graalvm.buildtools.examples</groupId>
48+
<artifactId>maven</artifactId>
49+
<version>1.0.0-SNAPSHOT</version>
50+
51+
<properties>
52+
<java.version>1.8</java.version>
53+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
54+
<junit.jupiter.version>5.13.0</junit.jupiter.version>
55+
<native.maven.plugin.version>0.11.0-SNAPSHOT</native.maven.plugin.version>
56+
<junit.platform.native.version>0.11.0-SNAPSHOT</junit.platform.native.version>
57+
</properties>
58+
59+
<dependencies>
60+
<dependency>
61+
<groupId>org.junit.jupiter</groupId>
62+
<artifactId>junit-jupiter</artifactId>
63+
<version>${junit.jupiter.version}</version>
64+
<scope>test</scope>
65+
</dependency>
66+
</dependencies>
67+
68+
<profiles>
69+
<profile>
70+
<id>native</id>
71+
<build>
72+
<plugins>
73+
<plugin>
74+
<groupId>org.apache.maven.plugins</groupId>
75+
<artifactId>maven-failsafe-plugin</artifactId>
76+
<version>3.5.3</version>
77+
<executions>
78+
<execution>
79+
<goals>
80+
<goal>integration-test</goal>
81+
<goal>verify</goal>
82+
</goals>
83+
</execution>
84+
</executions>
85+
</plugin>
86+
<plugin>
87+
<groupId>org.graalvm.buildtools</groupId>
88+
<artifactId>native-maven-plugin</artifactId>
89+
<version>${native.maven.plugin.version}</version>
90+
<extensions>true</extensions>
91+
<executions>
92+
<execution>
93+
<id>test-native</id>
94+
<goals>
95+
<goal>test</goal>
96+
</goals>
97+
<phase>verify</phase>
98+
</execution>
99+
</executions>
100+
</plugin>
101+
</plugins>
102+
</build>
103+
</profile>
104+
</profiles>
105+
106+
</project>

0 commit comments

Comments
 (0)