Support file-based reachability metadata repositories

See gh-32408
This commit is contained in:
Andy Wilkinson 2022-09-20 14:06:18 +01:00
parent 8323f24ccc
commit e8aa5680d6
13 changed files with 776 additions and 3 deletions

View File

@ -17,6 +17,7 @@
package org.springframework.boot.gradle.plugin;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import org.graalvm.buildtools.gradle.NativeImagePlugin;
@ -31,6 +32,7 @@ import org.gradle.api.file.FileCopyDetails;
import org.gradle.api.plugins.ExtensionAware;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
@ -87,17 +89,24 @@ class NativeImagePluginAction implements PluginApplicationAction {
private void copyReachabilityMetadataToBootJar(Project project, GraalVMExtension graalVmExtension) {
Path repositoryCacheDir = new File(project.getGradle().getGradleUserHomeDir(),
"native-build-tools/repositories").toPath();
project.getTasks().named(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class).configure((bootJar) -> {
NativeImageOptions options = graalVmExtension.getBinaries().named(NativeImagePlugin.NATIVE_MAIN_EXTENSION)
.get();
GraalVMReachabilityMetadataRepositoryExtension metadataRepositoryExtension = ((ExtensionAware) graalVmExtension)
.getExtensions().getByType(GraalVMReachabilityMetadataRepositoryExtension.class);
Property<URI> metadataRepositoryUri = metadataRepositoryExtension.getUri();
bootJar.from(options.getConfigurationFileDirectories())
.eachFile((file) -> normalizePathIfNecessary(repositoryCacheDir, file));
.eachFile((file) -> normalizePathIfNecessary(repositoryCacheDir, metadataRepositoryUri, file));
});
}
private void normalizePathIfNecessary(Path repositoryCacheDir, FileCopyDetails configurationFile) {
private void normalizePathIfNecessary(Path repositoryCacheDir, Property<URI> metadataRepositoryUri,
FileCopyDetails configurationFile) {
Path configurationFilePath = configurationFile.getFile().toPath();
if (configurationFilePath.startsWith(repositoryCacheDir)) {
Path repositoryMetadataRoot = ("file".equals(metadataRepositoryUri.get().getScheme()))
? Path.of(metadataRepositoryUri.get()) : repositoryCacheDir;
if (configurationFilePath.startsWith(repositoryMetadataRoot)) {
Path versionDir = configurationFilePath.getParent();
Path artifactDir = versionDir.getParent();
Path groupDir = artifactDir.getParent();

View File

@ -32,6 +32,7 @@ import org.junit.jupiter.api.TestTemplate;
import org.springframework.boot.gradle.junit.GradleCompatibility;
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
import org.springframework.util.FileSystemUtils;
import static org.assertj.core.api.Assertions.assertThat;
@ -68,6 +69,24 @@ class NativeImagePluginActionIntegrationTests {
"META-INF/native-image/org.jline/jline/3.21.0/resource-config.json");
}
@TestTemplate
void reachabilityMetadataConfigurationFilesFromFileRepositoryAreCopiedToJar() throws IOException {
writeDummyAotProcessorMainClass();
FileSystemUtils.copyRecursively(new File("src/test/resources/reachability-metadata-repository"),
new File(this.gradleBuild.getProjectDir(), "reachability-metadata-repository"));
BuildResult result = this.gradleBuild.build("bootJar");
assertThat(result.task(":bootJar").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
File jarFile = new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".jar");
assertThat(buildLibs.listFiles()).contains(jarFile);
assertThat(getEntryNames(jarFile)).contains(
"META-INF/native-image/ch.qos.logback/logback-classic/1.2.11/reflect-config.json",
"META-INF/native-image/org.jline/jline/3.21.0/jni-config.json",
"META-INF/native-image/org.jline/jline/3.21.0/proxy-config.json",
"META-INF/native-image/org.jline/jline/3.21.0/reflect-config.json",
"META-INF/native-image/org.jline/jline/3.21.0/resource-config.json");
}
private void writeDummyAotProcessorMainClass() {
File examplePackage = new File(this.gradleBuild.getProjectDir(), "src/main/java/org/springframework/boot");
examplePackage.mkdirs();

View File

@ -0,0 +1,26 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.boot.aot'
}
apply plugin: 'org.graalvm.buildtools.native'
repositories {
mavenCentral()
}
dependencies {
implementation "ch.qos.logback:logback-classic:1.2.11"
implementation "org.jline:jline:3.21.0"
}
graalvmNative {
metadataRepository {
uri(file("reachability-metadata-repository"))
}
// see https://github.com/graalvm/native-build-tools/issues/302
agent {
tasksToInstrumentPredicate = { t -> false } as java.util.function.Predicate<Test>
}
}

View File

@ -0,0 +1,299 @@
[
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.CallerDataConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.CallerDataConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.ClassOfCallerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.ContextNameConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.DateConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.ExtendedThrowableProxyConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.FileOfCallerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.LevelConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.LineOfCallerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.LineSeparatorConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.LocalSequenceNumberConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.LoggerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.MDCConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.MarkerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.MessageConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.MethodOfCallerConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.NopThrowableInformationConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.PrefixCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.PropertyConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.RelativeTimeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.RootCauseFirstThrowableProxyConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.ThreadConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.ThrowableProxyConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.classic.pattern.color.HighlightingCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.IdentityCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.ReplacingCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BlackCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BlueCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldBlueCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldCyanCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldGreenCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldMagentaCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldRedCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldWhiteCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.BoldYellowCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.CyanCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.GrayCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.GreenCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.MagentaCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.RedCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.WhiteCompositeConverter",
"allPublicConstructors": true
},
{
"condition": {
"typeReachable": "ch.qos.logback.classic.LoggerContext"
},
"name": "ch.qos.logback.core.pattern.color.YellowCompositeConverter",
"allPublicConstructors": true
},
{
"name": "org.slf4j.impl.StaticLoggerBinder"
}
]

View File

@ -0,0 +1,10 @@
[
{
"latest": true,
"metadata-version": "1.2.11",
"module": "ch.qos.logback:logback-classic",
"tested-versions": [
"1.2.11"
]
}
]

View File

@ -0,0 +1,10 @@
[
{
"directory": "org.jline/jline",
"module": "org.jline:jline"
},
{
"directory": "ch.qos.logback/logback-classic",
"module": "ch.qos.logback:logback-classic"
}
]

View File

@ -0,0 +1,6 @@
[
"jni-config.json",
"proxy-config.json",
"reflect-config.json",
"resource-config.json"
]

View File

@ -0,0 +1,128 @@
[
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiNativePty"
},
"fields": [
{
"name": "HAVE_ISATTY"
},
{
"name": "HAVE_TTYNAME"
},
{
"name": "TCSADRAIN"
},
{
"name": "TCSAFLUSH"
},
{
"name": "TCSANOW"
},
{
"name": "TIOCGETD"
},
{
"name": "TIOCGWINSZ"
},
{
"name": "TIOCSETD"
},
{
"name": "TIOCSWINSZ"
}
],
"name": "org.fusesource.jansi.internal.CLibrary"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.CLibrary$WinSize"
},
"name": "org.fusesource.jansi.internal.CLibrary$WinSize"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.CLibrary$Termios"
},
"name": "org.fusesource.jansi.internal.CLibrary$Termios"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32"
},
"name": "org.fusesource.jansi.internal.Kernel32"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$SMALL_RECT"
},
"name": "org.fusesource.jansi.internal.Kernel32$SMALL_RECT"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$COORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$COORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$CONSOLE_SCREEN_BUFFER_INFO"
},
"name": "org.fusesource.jansi.internal.Kernel32$CONSOLE_SCREEN_BUFFER_INFO"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$CHAR_INFO"
},
"name": "org.fusesource.jansi.internal.Kernel32$CHAR_INFO"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$KEY_EVENT_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$KEY_EVENT_RECORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$MOUSE_EVENT_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$MOUSE_EVENT_RECORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$WINDOW_BUFFER_SIZE_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$WINDOW_BUFFER_SIZE_RECORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$FOCUS_EVENT_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$FOCUS_EVENT_RECORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$MENU_EVENT_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$MENU_EVENT_RECORD"
},
{
"allDeclaredFields": true,
"condition": {
"typeReachable": "org.fusesource.jansi.internal.Kernel32$INPUT_RECORD"
},
"name": "org.fusesource.jansi.internal.Kernel32$INPUT_RECORD"
}
]

View File

@ -0,0 +1,10 @@
[
{
"condition": {
"typeReachable": "org.jline.utils.Signals"
},
"interfaces": [
"sun.misc.SignalHandler"
]
}
]

View File

@ -0,0 +1,104 @@
[
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiNativePty"
},
"name": "java.io.FileDescriptor",
"queriedMethods": [
{
"name": "<init>",
"parameterTypes": [
"int"
]
}
]
},
{
"condition": {
"typeReachable": "org.jline.terminal.TerminalBuilder"
},
"methods": [
{
"name": "current",
"parameterTypes": []
},
{
"name": "info",
"parameterTypes": []
},
{
"name": "parent",
"parameterTypes": []
}
],
"name": "java.lang.ProcessHandle"
},
{
"condition": {
"typeReachable": "org.jline.terminal.TerminalBuilder"
},
"methods": [
{
"name": "command",
"parameterTypes": []
}
],
"name": "java.lang.ProcessHandle$Info"
},
{
"condition": {
"typeReachable": "org.jline.builtins.Styles"
},
"methods": [
{
"name": "get",
"parameterTypes": []
}
],
"name": "org.jline.console.SystemRegistry"
},
{
"condition": {
"typeReachable": "org.jline.utils.Signals"
},
"methods": [
{
"name": "<init>",
"parameterTypes": [
"java.lang.String"
]
},
{
"name": "handle",
"parameterTypes": [
"sun.misc.Signal",
"sun.misc.SignalHandler"
]
}
],
"name": "sun.misc.Signal"
},
{
"condition": {
"typeReachable": "org.jline.utils.Signals"
},
"fields": [
{
"name": "SIG_DFL"
}
],
"name": "sun.misc.SignalHandler"
},
{
"allDeclaredClasses": true,
"allDeclaredConstructors": true,
"allDeclaredMethods": true,
"allPublicClasses": true,
"allPublicConstructors": true,
"allPublicMethods": true,
"condition": {
"typeReachable": "org.jline.terminal.TerminalBuilder"
},
"name": "sun.misc.SignalHandler"
}
]

View File

@ -0,0 +1,139 @@
{
"bundles": [],
"resources": {
"includes": [
{
"condition": {
"typeReachable": "org.jline.terminal.TerminalBuilder"
},
"pattern": "\\QMETA-INF/services/org.jline.terminal.spi.JansiSupport\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.TerminalBuilder"
},
"pattern": "\\QMETA-INF/services/org.jline.terminal.spi.JnaSupport\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiNativePty"
},
"pattern": "\\Qorg/fusesource/jansi/internal/native/Linux/x86_64/libjansi.so\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiNativePty"
},
"pattern": "\\QMETA-INF/native/windows64/jansi.dll\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiNativePty"
},
"pattern": "\\Qorg/fusesource/jansi/jansi.properties\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.jansi.JansiSupportImpl"
},
"pattern": "\\Qorg/fusesource/jansi/jansi.properties\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/capabilities.txt\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.Colors"
},
"pattern": "\\Qorg/jline/utils/colors.txt\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/ansi.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.DumbTerminal"
},
"pattern": "\\Qorg/jline/utils/dumb.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.DumbTerminal"
},
"pattern": "\\Qorg/jline/utils/dumb-color.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/rxvt.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/rxvt-basic.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/rxvt-unicode.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/rxvt-unicode-256color.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/screen.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/screen-256color.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.AbstractWindowsTerminal"
},
"pattern": "\\Qorg/jline/utils/windows.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.AbstractWindowsTerminal"
},
"pattern": "\\Qorg/jline/utils/windows-256color.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.terminal.impl.AbstractWindowsTerminal"
},
"pattern": "\\Qorg/jline/utils/windows-conemu.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/xterm.caps\\E"
},
{
"condition": {
"typeReachable": "org.jline.utils.InfoCmp"
},
"pattern": "\\Qorg/jline/utils/xterm-256color.caps\\E"
}
]
}
}

View File

@ -0,0 +1,10 @@
[
{
"latest": true,
"metadata-version": "3.21.0",
"module": "org.jline:jline",
"tested-versions": [
"3.21.0"
]
}
]