Skip to content

Commit

Permalink
Fixing tests and docs (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
lazar-mitrovic committed Jun 8, 2022
1 parent 1a90901 commit d39d6d8
Show file tree
Hide file tree
Showing 16 changed files with 191 additions and 62 deletions.
10 changes: 10 additions & 0 deletions docs/src/docs/asciidoc/maven-plugin.adoc
Expand Up @@ -118,6 +118,16 @@ Build Configuration]. It is also possible to customize the plugin within a
`<skipNativeBuild>`::
To skip generation of the native image, supply
`<skipNativeBuild>true</skipNativeBuild>` in the configuration of the plugin.
`<skipNativeTests>`::
To skip generation and execution of the native image compiled tests, supply
`<skipNativeTests>true</skipNativeTests>` to the configuration of the plugin.
`<debug>`::
If you want to enable generation of debugging information supply
`<debug>true</debug>` in the configuration of the plugin.
`<verbose>`::
If you want to enable verbose output during native-image building supply
`<verbose>true</verbose>` in the configuration of the plugin.

`<agent>`::
Configuration of the <<agent-support, native agent>>. See <<agent-support-enabling>>
and <<agent-support-configuring-options>> for details.
Expand Down
Expand Up @@ -56,6 +56,7 @@
import org.gradle.api.tasks.Optional;
import org.gradle.jvm.toolchain.JavaLauncher;

import java.util.List;
import java.util.Map;


Expand Down Expand Up @@ -180,14 +181,14 @@ public interface NativeImageOptions extends Named {
ConfigurableFileCollection getConfigurationFileDirectories();

/**
* Returns the map that as contains information about configuration that should be excluded
* during image building. It consists of a jar regular expression as a key and a resource
* regular expression as a value.
* Returns the MapProperty that contains information about configuration that should be excluded
* during image building. It consists of a dependency coordinates and a list of
* regular expressions that match resources that should be excluded as a value.
*
* @return a map of filters for configuration exclusion
*/
@Input
MapProperty<String, String> getExcludeConfig();
MapProperty<String, List<String>> getExcludeConfig();

@Nested
NativeResourcesOptions getResources();
Expand Down Expand Up @@ -222,7 +223,7 @@ public interface NativeImageOptions extends Named {
/**
* Adds a system property to be used by the native-image builder process.
*
* @param name The name of the property
* @param name The name of the property
* @param value The value for the property. May be null.
* @return this
*/
Expand Down
Expand Up @@ -64,6 +64,7 @@

import javax.inject.Inject;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
Expand Down Expand Up @@ -194,6 +195,16 @@ public String getName() {
@InputFiles
public abstract ConfigurableFileCollection getConfigurationFileDirectories();

/**
* Returns the MapProperty that contains information about configuration that should be excluded
* during image building. It consists of a dependency coordinates and a list of
* regular expressions that match resources that should be excluded as a value.
*
* @return a map of filters for configuration exclusion
*/
@Input
public abstract MapProperty<String, List<String>> getExcludeConfig();

@Nested
public abstract NativeResourcesOptions getResources();

Expand Down
Expand Up @@ -43,7 +43,9 @@

import org.graalvm.buildtools.gradle.dsl.NativeImageOptions;
import org.graalvm.buildtools.utils.NativeImageUtils;
import org.gradle.api.Project;
import org.gradle.api.Transformer;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.file.FileSystemLocation;
import org.gradle.api.file.RegularFile;
import org.gradle.api.provider.Provider;
Expand All @@ -66,17 +68,20 @@ public class NativeImageCommandLineProvider implements CommandLineArgumentProvid
private final Provider<String> outputDirectory;
private final Provider<RegularFile> classpathJar;
private final Provider<Boolean> useArgFile;
private final Project project;

public NativeImageCommandLineProvider(Provider<NativeImageOptions> options,
Provider<String> executableName,
Provider<String> outputDirectory,
Provider<RegularFile> classpathJar,
Provider<Boolean> useArgFile) {
Provider<Boolean> useArgFile,
Project project) {
this.options = options;
this.executableName = executableName;
this.outputDirectory = outputDirectory;
this.classpathJar = classpathJar;
this.useArgFile = useArgFile;
this.project = project;
}

@Nested
Expand Down Expand Up @@ -104,16 +109,32 @@ public List<String> asArguments() {
NativeImageOptions options = getOptions().get();
List<String> cliArgs = new ArrayList<>(20);

options.getExcludeConfig().get().forEach((jarPath, resourcePattern) -> {
cliArgs.add("--exclude-config");
cliArgs.add(jarPath);
cliArgs.add(resourcePattern);
options.getExcludeConfig().get().forEach((dependency, listOfResourcePatterns) -> {
// Resolve jar for this dependency.
project.getConfigurations().getByName("runtimeClasspath").getIncoming().artifactView(view -> {
view.setLenient(true);
view.componentFilter(id -> {
if (id instanceof ModuleComponentIdentifier) {
ModuleComponentIdentifier mid = (ModuleComponentIdentifier) id;
String gav = String.format("%s:%s",
mid.getGroup(),
mid.getModule()
);
return dependency.startsWith(gav);
}
return false;
});
}).getFiles().forEach(jarPath -> listOfResourcePatterns.forEach(resourcePattern -> {
cliArgs.add("--exclude-config");
cliArgs.add(jarPath.toPath().toAbsolutePath().toString());
cliArgs.add(String.format("\"%s\"", resourcePattern));
}));
});

cliArgs.add("-cp");
String classpathString = buildClasspathString(options);
cliArgs.add(classpathString);
appendBooleanOption(cliArgs, options.getDebug(), "-H:GenerateDebugInfo=1");
appendBooleanOption(cliArgs, options.getDebug(), "-g");
appendBooleanOption(cliArgs, options.getFallback().map(NEGATE), "--no-fallback");
appendBooleanOption(cliArgs, options.getVerbose(), "--verbose");
appendBooleanOption(cliArgs, options.getSharedLibrary(), "--shared");
Expand Down
Expand Up @@ -56,14 +56,7 @@
import org.gradle.api.provider.Property;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.*;
import org.gradle.process.ExecOperations;

import javax.inject.Inject;
Expand Down Expand Up @@ -155,7 +148,9 @@ private List<String> buildActualCommandLineArgs() {
// a mapped value before the task was called, when we are actually calling it...
getProviders().provider(() -> getOutputDirectory().getAsFile().get().getAbsolutePath()),
getClasspathJar(),
getUseArgFile()).asArguments();
getUseArgFile(),
getProject()
).asArguments();
}

// This property provides access to the service instance
Expand All @@ -165,7 +160,6 @@ private List<String> buildActualCommandLineArgs() {
public abstract Property<Object> getService();

@TaskAction
@SuppressWarnings("ConstantConditions")
public void exec() {
List<String> args = buildActualCommandLineArgs();
NativeImageOptions options = getOptions().get();
Expand Down
11 changes: 8 additions & 3 deletions native-maven-plugin/reproducers/issue-144/pom.xml
Expand Up @@ -100,9 +100,7 @@
<configuration>
<skip>false</skip>
<imageName>${imageName}</imageName>
<buildArgs>
<buildArg>--no-fallback</buildArg>
</buildArgs>
<fallback>false</fallback>
</configuration>
</plugin>
<plugin>
Expand All @@ -117,6 +115,13 @@
<configuration>
<source>${java.version}</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
Expand Down
Expand Up @@ -44,6 +44,20 @@ package org.graalvm.buildtools.maven
import spock.lang.Issue

class JavaApplicationFunctionalTest extends AbstractGraalVMMavenFunctionalTest {
def "proper options are added to the native-image invocation"() {
withSample("java-application")

when:
mvn '-Pnative', '-DskipTests', '-DnativeDryRun', '-DuseArgFile=false',
'-Dclasspath=/testcp', '-Ddebug', '-Dfallback=false', '-Dverbose', '-DsharedLibrary',
'-DquickBuild',
'package'

then:
buildSucceeded
outputContains "native-image -cp /testcp -g --no-fallback --verbose --shared -Ob"
}

def "can build and execute a native image with the Maven plugin"() {
withSample("java-application")

Expand Down
Expand Up @@ -100,6 +100,18 @@ class MetadataRepositoryFunctionalTest extends AbstractGraalVMMavenFunctionalTes
outputContains "[graalvm reachability metadata repository for org.graalvm.internal:library-with-reflection:1.5]: Configuration directory is org/graalvm/internal/library-with-reflection/1"
}

void "if excludeConfig is set it is added to the command line invocation"() {
given:
withSample("native-config-integration")

when:
mvn '-Pnative,metadataLocal,excludeConfigTest', '-DnativeDryRun', 'package'

then:
buildSucceeded
outputContains "native-image --exclude-config dummy/path/to/file.jar *"
}

void "if the path doesn't exist it throws an error"() {
given:
withSample("native-config-integration")
Expand Down
Expand Up @@ -142,6 +142,9 @@ public abstract class AbstractNativeMojo extends AbstractMojo {
@Parameter(property = "sharedLibrary", defaultValue = "false")
protected boolean sharedLibrary;

@Parameter(property = "quickBuild", defaultValue = "false")
protected boolean quickBuild;

@Parameter(property = "useArgFile")
protected Boolean useArgFile;

Expand Down Expand Up @@ -169,9 +172,16 @@ public abstract class AbstractNativeMojo extends AbstractMojo {
@Parameter(property = "jvmArgs")
protected List<String> jvmArgs;

@Parameter(property = "agent")
protected Map<String, Object> agent;
// As we are fetching this value by XML parsing in NativeExtension we only need this to keep IDE happy.

@Parameter(alias = "metadataRepository")
protected MetadataRepositoryConfiguration metadataRepositoryConfiguration;

@Parameter(property = NATIVE_IMAGE_DRY_RUN, defaultValue = "false")
protected boolean dryRun;

protected JvmReachabilityMetadataRepository metadataRepository;

@Component
Expand All @@ -194,15 +204,15 @@ protected List<String> getBuildArgs() throws MojoExecutionException {
excludeConfig.forEach(entry -> {
cliArgs.add("--exclude-config");
cliArgs.add(entry.getJarPath());
cliArgs.add(entry.getResourcePattern());
cliArgs.add(String.format("\"%s\"", entry.getResourcePattern()));
});
}

cliArgs.add("-cp");
cliArgs.add(getClasspath());

if (debug) {
cliArgs.add("-H:GenerateDebugInfo=1");
cliArgs.add("-g");
}
if (!fallback) {
cliArgs.add("--no-fallback");
Expand All @@ -213,6 +223,9 @@ protected List<String> getBuildArgs() throws MojoExecutionException {
if (sharedLibrary) {
cliArgs.add("--shared");
}
if (quickBuild) {
cliArgs.add("-Ob");
}

cliArgs.add("-H:Path=" + outputDirectory.toPath().toAbsolutePath());
cliArgs.add("-H:Name=" + imageName);
Expand All @@ -228,7 +241,7 @@ protected List<String> getBuildArgs() throws MojoExecutionException {
}

maybeAddGeneratedResourcesConfig(buildArgs);
maybeAddReachabilityMetadata(cliArgs);
maybeAddReachabilityMetadata(configFiles);

if (configFiles != null && !configFiles.isEmpty()) {
cliArgs.add("-H:ConfigurationFileDirectories=" +
Expand Down Expand Up @@ -356,12 +369,10 @@ protected void populateClasspath() throws MojoExecutionException {

protected String getClasspath() throws MojoExecutionException {
populateClasspath();

if (imageClasspath.isEmpty()) {
throw new MojoExecutionException("Image classpath is empty. " +
"Check if your classpath configuration is correct.");
}

return imageClasspath.stream()
.map(Path::toString)
.collect(Collectors.joining(File.pathSeparator));
Expand All @@ -387,7 +398,7 @@ protected void buildImage() throws MojoExecutionException {
String commandString = String.join(" ", processBuilder.command());
logger.info("Executing: " + commandString);

if (System.getProperty(NATIVE_IMAGE_DRY_RUN) != null) {
if (dryRun) {
logger.warn("Skipped native-image building due to `" + NATIVE_IMAGE_DRY_RUN + "` being specified.");
return;
}
Expand Down Expand Up @@ -460,16 +471,15 @@ public boolean isArtifactExcludedFromMetadataRepository(Artifact dependency) {
}
}

protected void maybeAddReachabilityMetadata(List<String> args) {
protected void maybeAddReachabilityMetadata(List<String> configDirs) {
if (isMetadataRepositoryEnabled() && !metadataRepositoryPaths.isEmpty()) {
String arg = metadataRepositoryPaths.stream()
.map(Path::toAbsolutePath)
.map(Path::toFile)
.map(File::getAbsolutePath)
.collect(Collectors.joining(","));

if (!arg.isEmpty()) {
args.add("-H:ConfigurationFileDirectories=" + arg);
configDirs.add(arg);
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions samples/java-application-with-reflection/pom.xml
Expand Up @@ -140,9 +140,7 @@
<configuration>
<!-- end::native-plugin-agent-options[] -->
<imageName>${imageName}</imageName>
<buildArgs>
<buildArg>--no-fallback</buildArg>
</buildArgs>
<fallback>false</fallback>
<!-- tag::native-plugin-agent-options[] -->
<agent>
<!-- end::native-plugin-agent-options[] -->
Expand Down Expand Up @@ -202,6 +200,14 @@
<configuration>
<source>${java.version}</source>
<target>1.8</target>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
Expand Down

0 comments on commit d39d6d8

Please sign in to comment.