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

Rework Maven plugin #247

Merged
merged 5 commits into from Jun 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-native-gradle-plugin.yml
Expand Up @@ -53,7 +53,7 @@ jobs:
strategy:
fail-fast: false
matrix:
gradle-version: ["current", "7.3.3", "7.2", "7.1", "6.8.3","6.7.1"]
lazar-mitrovic marked this conversation as resolved.
Show resolved Hide resolved
gradle-version: ["current", "7.3.3", "7.2", "7.1", "6.8.3", "6.7.1"]
graalvm-version: [ dev ]
java-version: [ 11 ]
os: [ ubuntu-20.04 ]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/asciidoc/gradle-plugin.adoc
Expand Up @@ -67,7 +67,7 @@ include::../snippets/gradle/kotlin/settings.gradle.kts[tags=pre-release, indent=
----
====

=== Installing GraalVM native image tool
=== Installing GraalVM Native Image tool

The plugin relies on Gradle's https://docs.gradle.org/7.1.1/userguide/toolchains.html[JVM toolchain support], allowing to decorrelate the tool used to run Gradle, the compiler used to build your application, and eventually the SDK used to generate a native image.

Expand Down
12 changes: 12 additions & 0 deletions docs/src/docs/asciidoc/index.adoc
Expand Up @@ -23,6 +23,18 @@ If you are interested in contributing, please refer to our https://github.com/gr
* Introduced the `metadataCopy` task.
* Introduced the concept of agent modes.
** Under the hood, the agent mode dictates what options are passed to the agent and how metadata produced by multiple runs get merged.
* Added `excludeConfig` configuration option that allows skipping of configuration files that are present in dependencies.
lazar-mitrovic marked this conversation as resolved.
Show resolved Hide resolved
* `useArgFile` is now set to true by default only on Windows.
* Added `quickBuild` configuration option.

==== Maven plugin
* Added support for GraalVM Reachability Metadata Repository.
* Completely reworked Maven plugin (should fix many of previous issues and inconsistencies between main and test builds).
* Added `classesDirectory`, `debug`, `fallback`, `verbose`, `sharedLibrary`, `configurationFileDirectories`, `excludeConfig`, `quickBuild`, and `jvmArgs` properties in order to match those present in the Gradle plugin.
+
See <<maven-plugin.adoc#,docs>> for more information.
* `useArgFile` is now set to true by default only on Windows.
* Changed lookup order for `native-image` discovery -- `GRAALVM_HOME`, `JAVA_HOME`, `PATH`.

=== Release 0.9.11

Expand Down
130 changes: 120 additions & 10 deletions docs/src/docs/asciidoc/maven-plugin.adoc
Expand Up @@ -114,10 +114,119 @@ Build Configuration]. It is also possible to customize the plugin within a
image name is not supplied, the artifact ID of the project will be used by default.
`<buildArgs>`::
If you want to pass additional arguments to the native image builder, use `<buildArgs>`
in the configuration of the plugin.
in the configuration of the plugin:
[source,xml]
----
<buildArgs>
<arg>--argument</arg>
</buildArgs>
----
`<skipNativeBuild>`::
To skip generation of the native image, supply
`<skipNativeBuild>true</skipNativeBuild>` in the configuration of the plugin.
To skip generation of the native image, supply the following in the configuration of the plugin:
[source,xml]
----
<skipNativeBuild>true</skipNativeBuild>
----
`<skipNativeTests>`::
To skip generation and execution of the native image compiled tests, supply the following in the configuration of the plugin:
[source,xml]
----
<skipNativeTests>true</skipNativeTests>
----
`<debug>`::
If you want to enable generation of debugging information supply the following in the configuration of the plugin:
[source,xml]
----
<debug>true</debug>
----
`<verbose>`::
If you want to enable verbose output during native-image building supply the following in the configuration of the plugin:
[source,xml]
----
<verbose>true</verbose>
----
`<sharedLibrary>`::
If you want to build image as a shared library supply the following in the configuration of the plugin:
[source,xml]
----
<sharedLibrary>true</sharedLibrary>
----
`<useArgFile>`::
If you want to use argument file for native-image building supply the following in the configuration of the plugin:
[source,xml]
----
<useArgFile>true</useArgFile>
----
`<quickBuild>`::
If you want to build the image using https://blogs.oracle.com/java/post/graalvm-enterprise-221--faster-smarter-leaner[quick build mode], supply the following in the configuration of the plugin (alternatively set the `GRAALVM_QUICK_BUILD` environment variable to `true`):
[source,xml]
----
<quickBuild>true</quickBuild>
lazar-mitrovic marked this conversation as resolved.
Show resolved Hide resolved
----

`<excludeConfig>`::
In order to exclude configuration from present jar files, specify:
[source,xml]
----
<excludeConfig>
<entry>
<jarPath>dummy/path/to/file.jar</jarPath>
<resourcePattern>*</resourcePattern>
</entry>
</excludeConfig>
----
`<environment>`::
To set environment options for native-image building supply the following in the configuration of the plugin:
[source,xml]
----
<environment>
<variable>value</variable>
</environment>
----
`<systemPropertyVariables>`::
To specify system properties used for native-image building supply the following in the configuration of the plugin:
[source,xml]
----
<systemPropertyVariables>
<propertyName>value</propertyName>
</systemPropertyVariables>
----
`<jvmArgs>`::
To specify JVM arguments used for native-image building supply the following in the configuration of the plugin:
[source,xml]
----
<jvmArgs>
<arg>argument1</arg>
<arg>argument2</arg>
</jvmArgs>
----
`<configurationFileDirectories>`::
If you want to specify custom directories where configuration files should be looked up, supply the following in the configuration of the plugin:
[source,xml]
----
<configurationFileDirectories>
<dir>path/to/dir</dir>
</configurationFileDirectories>
----
`<classpath`::
Sets a custom classpath instead of plugin generated one. Usage:
[source,xml]
----
<classpath>
<entry>path/to/file.jar</entry>
<entry>path/to/classes</entry>
</classpath>
----
`<classesDirectory>`::
If you want to specify custom path to packed JAR, or a custom directory that contains
only application classes, but want the plugin to still automatically add classpath entries for
dependencies, simply add:
[source,xml]
----
<classesDirectory>
path/to/dir
</classesDirectory>
----
`<agent>`::
Configuration of the <<agent-support, native agent>>. See <<agent-support-enabling>>
and <<agent-support-configuring-options>> for details.
Expand All @@ -126,15 +235,17 @@ For example, to build a native image named `executable-name` that uses
`org.example.ClassName` as its main class with assertions enabled, add the following
`<configuration>` block for the `native-maven-plugin`.

```xml
[source,xml]
----
<configuration>
<imageName>executable-name</imageName>
<mainClass>org.example.ClassName</mainClass>
<buildArgs>
<buildArg>--no-fallback</buildArg>
</buildArgs>
<fallback>false</fallback>
<verbose>true</verbose>
</configuration>
```
----

NOTE: Most of the aforementioned properties can also be set from command line as a part of Maven invocation -- for example if you want to temporarily enable verbose mode you can append `-Dverbose` to your Maven invocation.

NOTE: If you use GraalVM Enterprise as the `JAVA_HOME` environment, the plugin builds a native image with enterprise features enabled -- for example, an executable will automatically be built with https://medium.com/graalvm/isolates-and-compressed-references-more-flexible-and-efficient-memory-management-for-graalvm-a044cc50b67e[compressed references] and other optimizations enabled.

Expand All @@ -152,7 +263,7 @@ The `<buildArgs>` element can be combined between parent and children POMs. Supp
<imageName>${project.artifactId}</imageName>
<mainClass>${exec.mainClass}</mainClass>
<buildArgs>
<buildArg>--no-fallback<buildArg>
<buildArg>--no-fallback</buildArg>
</buildArgs>
</configuration>
</plugin>
Expand Down Expand Up @@ -323,7 +434,6 @@ Depending on the other plugins your build uses (typically the Spring Boot plugin
...
----


To be able to <<testing-support,execute tests in native mode>>, you will need more setup:

- Create a `src/assembly/test-jar-with-dependencies.xml` file with the following contents:
Expand Down
5 changes: 4 additions & 1 deletion docs/src/docs/snippets/gradle/groovy/build.gradle
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -119,9 +119,12 @@ graalvmNative {
verbose = true // Add verbose output, defaults to false
fallback = true // Sets the fallback mode of native-image, defaults to false
sharedLibrary = false // Determines if image is a shared library, defaults to false if `java-library` plugin isn't included
quickBuild = false // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable)

systemProperties = [name1: 'value1', name2: 'value2'] // Sets the system properties to use for the native image builder
configurationFileDirectories.from(file('src/my-config')) // Adds a native image configuration file directory, containing files like reflection configuration
excludeConfig.put("org.example.test", ["META-INF/native-image/*", "config/*"]) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates.
excludeConfig.put(file("path/to/artifact.jar"), listOf("META-INF/native-image/*", "config/*"))

// Advanced options
buildArgs.add('-H:Extra') // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
Expand Down
5 changes: 4 additions & 1 deletion docs/src/docs/snippets/gradle/kotlin/build.gradle.kts
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2022 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -77,9 +77,12 @@ graalvmNative {
verbose.set(true) // Add verbose output, defaults to false
fallback.set(true) // Sets the fallback mode of native-image, defaults to false
sharedLibrary.set(false) // Determines if image is a shared library, defaults to false if `java-library` plugin isn't included
quickBuild.set(false) // Determines if image is being built in quick build mode (alternatively use GRAALVM_QUICK_BUILD environment variable)

systemProperties.putAll(mapOf("name1" to "value1", "name2" to "value2")) // Sets the system properties to use for the native image builder
configurationFileDirectories.from(file("src/my-config")) // Adds a native image configuration file directory, containing files like reflection configuration
excludeConfig.put("org.example.test", listOf("META-INF/native-image/*", "config/*")) // Excludes configuration that matches one of given regexes from JAR of dependency with said coordinates.
excludeConfig.put(file("path/to/artifact.jar"), listOf("META-INF/native-image/*", "config/*"))

// Advanced options
buildArgs.add("-H:Extra") // Passes '-H:Extra' to the native image builder options. This can be used to pass parameters which are not directly supported by this extension
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -74,6 +74,7 @@
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.ConfigurationContainer;
import org.gradle.api.artifacts.ModuleVersionIdentifier;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.attributes.Attribute;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.file.ArchiveOperations;
Expand Down Expand Up @@ -114,6 +115,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
Expand All @@ -126,6 +128,7 @@
import static org.graalvm.buildtools.gradle.internal.GradleUtils.transitiveProjectArtifacts;
import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.graalvmHomeProvider;
import static org.graalvm.buildtools.utils.SharedConstants.AGENT_PROPERTY;
import static org.graalvm.buildtools.utils.SharedConstants.IS_WINDOWS;

/**
* Gradle plugin for GraalVM Native Image.
Expand Down Expand Up @@ -170,7 +173,7 @@ public void apply(Project project) {

logger = GraalVMLogger.of(project.getLogger());
DefaultGraalVmExtension graalExtension = (DefaultGraalVmExtension) registerGraalVMExtension(project);
graalExtension.getUseArgFile().convention(true);
graalExtension.getUseArgFile().convention(IS_WINDOWS);
project.getPlugins()
.withType(JavaPlugin.class, javaPlugin -> configureJavaProject(project, nativeImageServiceProvider, graalExtension));

Expand Down Expand Up @@ -571,10 +574,12 @@ private static NativeImageOptions createMainOptions(GraalVMExtension graalExtens
"main",
JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME
);
setupExtensionConfigExcludes(buildExtension, configs);
buildExtension.getClasspath().from(configs.getImageClasspathConfiguration());
return buildExtension;
}


private static NativeImageOptions createTestOptions(GraalVMExtension graalExtension,
String binaryName,
Project project,
Expand All @@ -586,6 +591,8 @@ private static NativeImageOptions createTestOptions(GraalVMExtension graalExtens
binaryName,
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME
);
setupExtensionConfigExcludes(testExtension, configs);

testExtension.getMainClass().set("org.graalvm.junit.platform.NativeImageJUnitLauncher");
testExtension.getMainClass().finalizeValue();
testExtension.getImageName().convention(mainExtension.getImageName().map(name -> name + SharedConstants.NATIVE_TESTS_SUFFIX));
Expand All @@ -600,6 +607,48 @@ private static NativeImageOptions createTestOptions(GraalVMExtension graalExtens
return testExtension;
}

private static void addExcludeConfigArg(List<String> args, Path jarPath, List<String> listOfResourcePatterns) {
listOfResourcePatterns.forEach(resourcePattern -> {
args.add("--exclude-config");
args.add(jarPath.toAbsolutePath().toString());
args.add(String.format("\"%s\"", resourcePattern));
});
}

private static void setupExtensionConfigExcludes(NativeImageOptions options, NativeConfigurations configs) {
options.getExcludeConfigArgs().set(options.getExcludeConfig().map(excludedConfig -> {
List<String> args = new ArrayList<>();
excludedConfig.forEach((entry, listOfResourcePatterns) -> {
if (entry instanceof File) {
addExcludeConfigArg(args, ((File) entry).toPath(), listOfResourcePatterns);
} else if (entry instanceof String) {
String dependency = (String) entry;
// Resolve jar for this dependency.
configs.getImageClasspathConfiguration().getIncoming().artifactView(view -> {
view.setLenient(true);
view.componentFilter(id -> {
if (id instanceof ModuleComponentIdentifier) {
ModuleComponentIdentifier mid = (ModuleComponentIdentifier) id;
String gav = String.format("%s:%s:%s",
mid.getGroup(),
mid.getModule(),
mid.getVersion()
);
return gav.startsWith(dependency);
}
return false;
});
}).getFiles().getFiles().stream()
.map(File::toPath)
.forEach(jarPath -> addExcludeConfigArg(args, jarPath, listOfResourcePatterns));
} else {
throw new UnsupportedOperationException("Expected File or GAV coordinate for excludeConfig option, got " + entry.getClass());
}
});
return args;
}));
}

private static List<String> agentSessionDirectories(Directory outputDirectory) {
return Arrays.stream(outputDirectory.getAsFile().listFiles(file -> file.isDirectory() && file.getName().startsWith("session-"))).map(File::getAbsolutePath).collect(Collectors.toList());
}
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
Expand Down Expand Up @@ -99,7 +99,7 @@ public interface GraalVMExtension {

/**
* Property driving the use of @-arg files when invoking native image.
* This is enabled by default. For older native-image versions, this
* This is enabled by default on Windows. For older native-image versions, this
* needs to be disabled.
*
* @return the argument file property
Expand Down