Skip to content

Commit

Permalink
Merge branch 'master' into fix-path-whitespaces-args
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarosanchez authored Sep 4, 2024
2 parents 5a86516 + 2c8c2a7 commit 8fcddbf
Show file tree
Hide file tree
Showing 15 changed files with 177 additions and 240 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ public void onLoad(NativeImageConfiguration config) {
"org.junit.platform.engine.UniqueIdFormat",
"org.junit.platform.commons.util.ReflectionUtils",
// https://github.com/graalvm/native-build-tools/issues/300
"org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener"
"org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener",
// https://github.com/graalvm/native-build-tools/issues/602
"org.junit.platform.commons.util.LruCache"
);

if (getMajorJDKVersion() >= 21) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,21 @@
*/
package org.graalvm.buildtools.agent;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.file.CopyOption;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class AgentConfiguration implements Serializable {

private static final String DEFAULT_ACCESS_FILTER_FILE = "/access-filter.json";
private final Collection<String> callerFilterFiles;
private final Collection<String> accessFilterFiles;
private final Boolean builtinCallerFilter;
Expand Down Expand Up @@ -88,6 +96,7 @@ public AgentConfiguration(Collection<String> callerFilterFiles,
}

public List<String> getAgentCommandLine() {
addDefaultAccessFilter();
List<String> cmdLine = new ArrayList<>(agentMode.getAgentCommandLine());
appendOptionToValues("caller-filter-file=", callerFilterFiles, cmdLine);
appendOptionToValues("access-filter-file=", accessFilterFiles, cmdLine);
Expand Down Expand Up @@ -127,4 +136,34 @@ private void addToCmd(String option, Boolean value, List<String> cmdLine) {
}
}

private void addDefaultAccessFilter() {
if (accessFilterFiles == null) {
// this could only happen if we instantiated disabled agent configuration
return;
}

String tempDir = System.getProperty("java.io.tmpdir");
Path agentDir = Path.of(tempDir).resolve("agent-config");
Path accessFilterFile = agentDir.resolve("access-filter.json");
if (Files.exists(accessFilterFile)) {
accessFilterFiles.add(accessFilterFile.toString());
return;
}

try(InputStream accessFilter = AgentConfiguration.class.getResourceAsStream(DEFAULT_ACCESS_FILTER_FILE)) {
if (accessFilter != null) {
if (!Files.exists(agentDir)) {
Files.createDirectory(agentDir);
}

Files.copy(accessFilter, accessFilterFile, StandardCopyOption.REPLACE_EXISTING);
accessFilterFiles.add(accessFilterFile.toString());
} else {
throw new IOException("Cannot find access-filter.json on default location: " + DEFAULT_ACCESS_FILTER_FILE);
}
} catch (IOException e) {
throw new RuntimeException("Cannot add default access-filter.json" ,e);
}
}

}
13 changes: 13 additions & 0 deletions common/utils/src/main/resources/access-filter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"rules": [
{
"includeClasses": "**"
},
{
"excludeClasses": "org.gradle.**"
},
{
"excludeClasses": "org.junit.**"
}
]
}
2 changes: 2 additions & 0 deletions docs/src/docs/asciidoc/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ If you are using alternative build systems, see <<alternative-build-systems.adoc
=== Release 0.10.3

- Remove usage of macro from merger tool initialization and throw better error if executable does not exist
- Add support for the new reachability-metadata.json config file
- Remove custom post-processing task for filtering config files entries and use access-filter.json instead

==== Gradle plugin

Expand Down
2 changes: 1 addition & 1 deletion docs/src/docs/asciidoc/maven-plugin.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Build Configuration]. It is also possible to customize the plugin within a
<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`):
If you want to build the image using https://www.graalvm.org/latest/reference-manual/native-image/overview/BuildOutput/#qbm-use-quick-build-mode-for-faster-builds[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>
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[versions]
# Project versions
nativeBuildTools = "0.10.3-SNAPSHOT"
metadataRepository = "0.3.8"
metadataRepository = "0.3.9"

# External dependencies
spock = "2.1-groovy-3.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,32 @@
package org.graalvm.buildtools.gradle

import org.graalvm.buildtools.gradle.fixtures.AbstractFunctionalTest
import org.graalvm.buildtools.gradle.fixtures.GraalVMSupport
import org.graalvm.buildtools.utils.NativeImageUtils
import spock.lang.Unroll

class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest {

def getCurrentJDKVersion() {
return NativeImageUtils.getMajorJDKVersion(GraalVMSupport.getGraalVMHomeVersionString())
}

def metadataInSingleConfigFile() {
return getCurrentJDKVersion() >= 23
}

def metadataExistsAt(String path) {
if (metadataInSingleConfigFile()) {
return file("${path}/reachability-metadata.json").exists()
}

boolean allFilesExist = ['jni', 'proxy', 'reflect', 'resource', 'serialization'].every { name ->
file("${path}/${name}-config.json").exists()
}

return allFilesExist
}

@Unroll("agent is not passed and the application fails with JUnit Platform #junitVersion")
def "agent is not passed"() {
given:
Expand Down Expand Up @@ -94,18 +116,13 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest {
""".trim()

and:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
assert file("build/native/agent-output/test/${name}-config.json").exists()
}
assert metadataExistsAt("build/native/agent-output/test")

when:
run 'metadataCopy'

then:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
assert file("build/native/metadataCopyTest/${name}-config.json").exists()
}

assert metadataExistsAt("build/native/metadataCopyTest")

where:
junitVersion = System.getProperty('versions.junit')
Expand All @@ -125,7 +142,11 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest {
}

and:
assert file("build/native/agent-output/test/reflect-config.json").text.contains("\"condition\"")
if (metadataInSingleConfigFile()) {
assert file("build/native/agent-output/test/reachability-metadata.json").text.contains("\"condition\"")
} else {
assert file("build/native/agent-output/test/reflect-config.json").text.contains("\"condition\"")
}

where:
junitVersion = System.getProperty('versions.junit')
Expand All @@ -148,22 +169,26 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest {
}

and:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
assert file("build/native/agent-output/run/${name}-config.json").exists()
}
assert metadataExistsAt("build/native/agent-output/run")

when:
run'metadataCopy', '--task', 'run', '--dir', metadata_dir
run 'metadataCopy', '--task', 'run', '--dir', metadata_dir

then:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
assert file("${metadata_dir}/${name}-config.json").exists()
}
assert metadataExistsAt(metadata_dir)

and:
var reflect_config = file("${metadata_dir}/reflect-config.json")
var reflect_config_contents = reflect_config.text
assert reflect_config_contents.contains("DummyClass") && reflect_config_contents.contains("org.graalvm.demo.Message")
if (metadataInSingleConfigFile()) {
var reachabilityMetadata = file("${metadata_dir}/reachability-metadata.json")
var reachabilityMetadataContents = reachabilityMetadata.text
println reachabilityMetadataContents
assert reachabilityMetadataContents.contains("DummyClass"), reachabilityMetadataContents
assert reachabilityMetadataContents.contains("org.graalvm.demo.Message"), reachabilityMetadataContents
} else {
var reflect_config = file("${metadata_dir}/reflect-config.json")
var reflect_config_contents = reflect_config.text
assert reflect_config_contents.contains("DummyClass") && reflect_config_contents.contains("org.graalvm.demo.Message")
}

when:
run 'nativeRun'
Expand All @@ -190,9 +215,7 @@ class JavaApplicationWithAgentFunctionalTest extends AbstractFunctionalTest {
}

and:
['jni', 'proxy', 'reflect', 'resource', 'serialization'].each { name ->
assert file("build/native/agent-output/run/${name}-config.json").exists()
}
assert metadataExistsAt("build/native/agent-output/run")

when:
run'run', '-Pagent', '--configuration-cache', '--rerun-tasks'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@
import org.graalvm.buildtools.gradle.tasks.NativeRunTask;
import org.graalvm.buildtools.gradle.tasks.actions.CleanupAgentFilesAction;
import org.graalvm.buildtools.gradle.tasks.actions.MergeAgentFilesAction;
import org.graalvm.buildtools.gradle.tasks.actions.ProcessGeneratedGraalResourceFilesAction;
import org.graalvm.buildtools.utils.SharedConstants;
import org.graalvm.reachability.DirectoryConfiguration;
import org.gradle.api.Action;
Expand Down Expand Up @@ -871,11 +870,6 @@ public void execute(@Nonnull Task task) {
execOperations));

taskToInstrument.doLast(new CleanupAgentFilesAction(mergeInputDirs, fileOperations));

taskToInstrument.doLast(new ProcessGeneratedGraalResourceFilesAction(
outputDir,
graalExtension.getAgent().getFilterableEntries()
));
}

private static void injectTestPluginDependencies(Project project, Property<Boolean> testSupportEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import org.gradle.jvm.toolchain.JavaToolchainService;

import javax.inject.Inject;
import java.util.Arrays;

public abstract class DefaultGraalVmExtension implements GraalVMExtension {
private final transient NamedDomainObjectContainer<NativeImageOptions> nativeImages;
Expand All @@ -79,7 +78,6 @@ public DefaultGraalVmExtension(NamedDomainObjectContainer<NativeImageOptions> na
agentOpts.getEnabled().convention(false);
agentOpts.getModes().getConditional().getParallel().convention(true);
agentOpts.getMetadataCopy().getMergeWithExisting().convention(false);
agentOpts.getFilterableEntries().convention(Arrays.asList("org.gradle.", "org.junit."));
agentOpts.getBuiltinHeuristicFilter().convention(true);
agentOpts.getBuiltinCallerFilter().convention(true);
agentOpts.getEnableExperimentalPredefinedClasses().convention(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,29 +91,29 @@ public static File findNativeImageExecutable(Property<JavaLauncher> javaLauncher
executablePath = metadata.getInstallationPath().file("bin/" + NATIVE_IMAGE_EXE).getAsFile();
}

try {
if (!executablePath.exists()) {
logger.log("Native Image executable wasn't found. We will now try to download it. ");
File graalVmHomeGuess = executablePath.getParentFile();

File guPath = graalVmHomeGuess.toPath().resolve(GU_EXE).toFile();
if (!guPath.exists()) {
throw new GradleException("'" + GU_EXE + "' at '" + guPath + "' tool wasn't found. This probably means that JDK at isn't a GraalVM distribution.");
}
ExecResult res = execOperations.exec(spec -> {
spec.args("install", "native-image");
spec.setExecutable(Paths.get(graalVmHomeGuess.getAbsolutePath(), GU_EXE));
});
if (res.getExitValue() != 0) {
throw new GradleException("Native Image executable wasn't found, and '" + GU_EXE + "' tool failed to install it.");
}
diagnostics.withGuInstall();
File graalVmHomeGuess = executablePath.getParentFile();
File guPath = graalVmHomeGuess.toPath().resolve(GU_EXE).toFile();
if (guPath.exists() && !executablePath.exists()) {
logger.log("Native Image executable wasn't found. We will now try to download it. ");

ExecResult res = execOperations.exec(spec -> {
spec.args("install", "native-image");
spec.setExecutable(Paths.get(graalVmHomeGuess.getAbsolutePath(), GU_EXE));
});
if (res.getExitValue() != 0) {
throw new GradleException("Native Image executable wasn't found, and '" + GU_EXE + "' tool failed to install it.\n" +
"Make sure to declare the GRAALVM_HOME or JAVA_HOME environment variable or install GraalVM with " +
"native-image in a standard location recognized by Gradle Java toolchain support");
}
} catch (GradleException e) {
throw new GradleException("Determining GraalVM installation failed with message: " + e.getMessage() + "\n\n"
+ "Make sure to declare the GRAALVM_HOME environment variable or install GraalVM with " +
"native-image in a standard location recognized by Gradle Java toolchain support");
diagnostics.withGuInstall();
}

if (!executablePath.exists()) {
throw new GradleException(executablePath + " wasn't found. This probably means that JDK isn't a GraalVM distribution.\n" +
"Make sure to declare the GRAALVM_HOME or JAVA_HOME environment variable or install GraalVM with" +
"native-image in a standard location recognized by Gradle Java toolchain support");
}

diagnostics.withExecutablePath(executablePath);
return executablePath;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;

import static org.graalvm.buildtools.gradle.internal.NativeImageExecutableLocator.findNativeImageExecutable;
Expand Down Expand Up @@ -94,8 +95,11 @@ public MergeAgentFilesAction(Provider<Boolean> isMergingEnabled,
this.noLauncherProperty = objectFactory.property(JavaLauncher.class);
}

private static final Set<String> METADATA_FILES = Set.of("reflect-config.json", "jni-config.json", "proxy-config.json", "resource-config.json", "reachability-metadata.json");

private static boolean isConfigDir(String dir) {
return Arrays.stream(new File(dir).listFiles()).anyMatch(file -> file.getName().equals("reflect-config.json"));
return Arrays.stream(new File(dir).listFiles())
.anyMatch(file -> METADATA_FILES.contains(file.getName()));
}

@Override
Expand Down
Loading

0 comments on commit 8fcddbf

Please sign in to comment.