Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maven plugin fixes #274

Merged
merged 3 commits into from
Aug 4, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Final Maven changes
Silence noisy tests
Fix docs
Make sure that GraalVM java executable gets used when attaching the agent
Add implementation dependency on svm.jar
Add changelog entries

Signed-off-by: Lazar Mitrović <lazar.mitrovic@oracle.com>
  • Loading branch information
lazar-mitrovic committed Aug 4, 2022
commit 0bdea33ff54047ff24c7a1b5101cdd4fb72b3240
15 changes: 12 additions & 3 deletions docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,26 @@ If you are using alternative build systems, see <<alternative-build-systems.adoc

[[changelog]]
== Changelog

=== Release 0.9.14

=== Gradle plugin
==== Gradle plugin
* Add ability to set environment variables to the native image builder process
* Argument files are now stored in the `build` directory (workaround for absolute path issue on Windows with older GraalVM versions)

==== Maven plugin
* Added `native:compile` forking goal that can be started from the command line as `mvn native:compile`.
* Argument files are now stored in the `target` directory (workaround for absolute path issue on Windows with older GraalVM versions).
* Default and test outputs are now much less noisy.
* When running tests in JVM mode with the native-image-agent, GraalVM's `java` executable is now always used.
* Maven plugin now shouldn't require that JVM running it must be GraalVM.

=== Release 0.9.13

=== Gradle plugin
==== Gradle plugin
* Reverted a change in the `NativeImagePlugin` that removed publicly accessible constants. This should prevent breakage of external plugins.

=== JUnit testing support
==== JUnit testing support
* Adapted the JUnit automatic metadata registration to changes in annotation handling on newer native image versions.

=== Release 0.9.12
Expand Down
2 changes: 2 additions & 0 deletions docs/src/docs/asciidoc/maven-plugin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ If the heuristics fail with the `no main manifest attribute, in target/<name>.ja
specified in the `<configuration>` node of the plugin.
When `mvn -Pnative package` completes, an executable is ready for use, generated in the `target` directory of the project.

NOTE: Building native image without attaching to the `package` phase can be done by invoking the forking `compile` goal directly, e.g. `mvn native:compile`

[TIP]
.Testing pre-releases
====
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ protected void executeMaven() {
spec.setClasspath(getMavenEmbedderClasspath());
spec.getMainClass().set("org.apache.maven.cli.MavenCli");
spec.systemProperty("maven.multiModuleProjectDirectory", projectdir.getAbsolutePath());
spec.systemProperty("org.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener", "warn");
prepareSpec(spec);
List<String> arguments = new ArrayList<>();
arguments.addAll(Arrays.asList(
"--errors",
"-U",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
"--settings", settingsFile.getAbsolutePath(),
"--file", pomFile.getAbsolutePath()
Expand Down
1 change: 1 addition & 0 deletions native-maven-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ dependencies {
implementation(libs.utils)
implementation(libs.jackson.databind)
implementation(libs.jvmReachabilityMetadata)
implementation(libs.graalvm.svm)

compileOnly(libs.maven.pluginApi)
compileOnly(libs.maven.core)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest {
withSample("java-application-with-custom-packaging")

when:
mvn 'package', '-Dpackaging=native-image', 'exec:exec@native'
mvnDebug 'package', '-Dpackaging=native-image', 'exec:exec@native'

then:
buildSucceeded
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
when:
// Run Maven in debug mode (-X) in order to capture the command line arguments
// used to launch Surefire with the agent.
mvn '-X', '-Pnative', 'test', '-DskipNativeTests'
mvnDebug '-Pnative', 'test', '-DskipNativeTests'

then:
// Agent is used with Surefire
Expand Down Expand Up @@ -85,7 +85,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
when:
// Run Maven in debug mode (-X) in order to capture the command line arguments
// used to launch Surefire with the agent.
mvn '-X', '-Pnative', 'test'
mvnDebug '-Pnative', 'test'

then:
outputContains """
Expand Down Expand Up @@ -162,7 +162,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
when:
// Run Maven in debug mode (-X) in order to capture the command line arguments
// used to launch Surefire with the agent.
mvn '-X', '-Pnative', '-DagentOptions=periodic-config', 'test'
mvnDebug '-Pnative', '-DagentOptions=periodic-config', 'test'

then:
outputContains """
Expand Down Expand Up @@ -214,7 +214,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
withSample("java-application-with-reflection")

when:
mvn '-X', '-Pnative', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'
mvnDebug '-Pnative', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'

then:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
Expand Down Expand Up @@ -246,7 +246,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
withSample("java-application-with-reflection")

when:
mvn '-X', '-Pnative', '-Dagent=false', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'
mvnDebug '-Pnative', '-Dagent=false', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'

then:
outputDoesNotContain '-agentlib:native-image-agent'
Expand All @@ -263,7 +263,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractGraalVMMavenFunctio
withSample("java-application-with-reflection")

when:
mvn '-X', '-Pnative', '-DagentOptions=periodic-config', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'
mvnDebug '-Pnative', '-DagentOptions=periodic-config', '-DskipTests=true', '-DskipNativeBuild=true', 'package', 'exec:exec@java-agent'

then:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,9 @@ protected void warnIfWrongMetaInfLayout(Path jarFilePath, Artifact artifact) thr
valid = valid && relativeSubDir.getName(0).toString().equals(artifact.getGroupId());
valid = valid && relativeSubDir.getName(1).toString().equals(artifact.getArtifactId());
if (!valid) {
String example = NATIVE_IMAGE_META_INF + "/${groupId}/${artifactId}/" + NATIVE_IMAGE_PROPERTIES_FILENAME;
logger.warn(nativeImageProperty.toUri() + " does not match recommended " + example + " layout.");
String example = NATIVE_IMAGE_META_INF + "/%s/%s/" + NATIVE_IMAGE_PROPERTIES_FILENAME;
example = String.format(example, artifact.getGroupId(), artifact.getArtifactId());
logger.warn("Properties file at '" + nativeImageProperty.toUri() + "' does not match the recommended '" + example + "' layout.");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,12 @@

/**
* This goal builds native images.
* It can be invoked using `mvn native:compile`.
* It should be invoked from the command line as a single goal (`mvn native:compile`).
*/
@Mojo(name = "compile", defaultPhase = LifecyclePhase.PACKAGE,
requiresDependencyResolution = ResolutionScope.RUNTIME,
requiresDependencyCollection = ResolutionScope.RUNTIME)
@Execute(phase = LifecyclePhase.PACKAGE)
@SuppressWarnings("unused")
public class NativeCompileMojo extends NativeCompileNoForkMojo {
// no-op
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public class NativeExtension extends AbstractMavenLifecycleParticipant implement
private static final String JUNIT_PLATFORM_LISTENERS_UID_TRACKING_OUTPUT_DIR = "junit.platform.listeners.uid.tracking.output.dir";
private static final String NATIVEIMAGE_IMAGECODE = "org.graalvm.nativeimage.imagecode";

private Logger logger;
private static Logger logger;

@Override
public void enableLogging(Logger logger) {
Expand All @@ -92,6 +92,8 @@ static String testIdsDirectory(String baseDir) {
return baseDir + File.separator + "test-ids";
}

private static String graalvmJava;

static String buildAgentArgument(String baseDir, Context context, List<String> agentOptions) {
List<String> options = new ArrayList<>(agentOptions);
String effectiveOutputDir = agentOutputDirectoryFor(baseDir, context);
Expand All @@ -115,6 +117,12 @@ static String agentOutputDirectoryFor(String baseDir, Context context) {

@Override
public void afterProjectsRead(MavenSession session) {
try {
graalvmJava = Utils.getNativeImage(logger).getParent().resolve("java").toString();
} catch (MojoExecutionException e) {
throw new RuntimeException(e);
}

for (MavenProject project : session.getProjects()) {
Build build = project.getBuild();
withPlugin(build, "native-maven-plugin", nativePlugin -> {
Expand Down Expand Up @@ -159,12 +167,7 @@ public void afterProjectsRead(MavenSession session) {
for (Xpp3Dom child : children) {
commandlineArgs.addChild(child);
}
Xpp3Dom executable = findOrAppend(config, "executable");
try {
executable.setValue(Utils.getNativeImage(logger).getParent().resolve("java").toString());
} catch (MojoExecutionException e) {
throw new RuntimeException(e);
}
findOrAppend(config, "executable").setValue(graalvmJava);
}
})
);
Expand Down Expand Up @@ -318,6 +321,7 @@ private static void configureAgentForSurefire(Plugin surefirePlugin, String agen
Xpp3Dom argLine = new Xpp3Dom("argLine");
argLine.setValue(agentArgument);
configuration.addChild(argLine);
findOrAppend(configuration, "jvm").setValue(graalvmJava);
});
}

Expand Down
6 changes: 6 additions & 0 deletions native-maven-plugin/src/seeding-build/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.jupiter.version>5.8.1</junit.jupiter.version>
<graalvm.version>22.0.0</graalvm.version>
<mainClass>org.graalvm.demo.Application</mainClass>
</properties>

Expand All @@ -62,6 +63,11 @@
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.graalvm.nativeimage</groupId>
<artifactId>svm</artifactId>
<version>${graalvm.version}</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,24 +139,61 @@ abstract class AbstractGraalVMMavenFunctionalTest extends Specification {
}

void mvn(List<String> args) {
mvn(args as String[])
Map<String, String> systemProperties = [
"org.apache.http" : "off",
"org.apache.http.wire" : "off",
].collectEntries { key, value ->
["org.slf4j.simpleLogger.log.${key}".toString(), value]
}
mvn(args, systemProperties)
}

void mvn(String... args) {
System.out.println("Running copy of maven project `" + testOrigin + "` with `" + args + "`");
mvn(args.toList())
}

void mvn(List<String> args, Map<String, String> systemProperties) {
System.out.println("Running copy of maven project `" + testOrigin + "` with " + args);
var resultingSystemProperties = [
"common.repo.uri": System.getProperty("common.repo.uri"),
"seed.repo.uri": System.getProperty("seed.repo.uri"),
"maven.repo.local": testDirectory.resolve("local-repo").toFile().absolutePath
]
resultingSystemProperties.putAll(systemProperties)

result = executor.execute(
testDirectory.toFile(),
[
"org.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener": "warn",
"common.repo.uri": System.getProperty("common.repo.uri"),
"seed.repo.uri": System.getProperty("seed.repo.uri"),
"maven.repo.local": testDirectory.resolve("local-repo").toFile().absolutePath
],
resultingSystemProperties,
[*injectedSystemProperties,
*args],
new File(System.getProperty("maven.settings"))
)
System.out.println("Exit code is ${result.exitCode}")

}

void mvnDebug(String... args) {
Map<String, String> systemProperties = [
"org.apache.http" : "off",
"org.apache.http.wire" : "off",
"org.apache.maven.cli.transfer.Slf4jMavenTransferListener" : "warn",
"org.eclipse.aether.internal.impl.DefaultTransporterProvider" : "error",
"org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider": "error",
"org.eclipse.aether.internal.impl.TrackingFileManager" : "error",
"org.eclipse.aether.internal.impl.DefaultArtifactResolver" : "error",
"org.codehaus.plexus.PlexusContainer" : "error",
"org.apache.maven.plugin.internal.DefaultPluginDependenciesResolver" : "error",
"org.apache.maven.shared.filtering.DefaultMavenFileFilter" : "error",
"org.codehaus.mojo.exec.ExecMojo" : "debug",
// This is THE logger we need for checking java execution
"org.apache.maven.lifecycle.internal.LifecycleDebugLogger" : "error"
].collectEntries { key, value ->
["org.slf4j.simpleLogger.log.${key}".toString(), value]
}

ArrayList<String> resultingArgs = args.toList()
resultingArgs.add(0, "-X")
mvn(resultingArgs, systemProperties)
}

boolean isDidNotCrash() {
Expand Down