Skip to content

Commit

Permalink
Merge pull request #12344 from zakkak/fix-oracle-graal-2841
Browse files Browse the repository at this point in the history
Don't re-initialize ThreadLocalRandom in GraalVM > 20.2
  • Loading branch information
gsmet authored Sep 30, 2020
2 parents 73edfa8 + 51fc58b commit 51a6f7d
Showing 1 changed file with 64 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,52 +105,12 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa
String noPIE = "";

boolean isContainerBuild = nativeConfig.containerRuntime.isPresent() || nativeConfig.containerBuild;
if (isContainerBuild) {
nativeImage = setupContainerBuild(nativeConfig, processInheritIODisabled, outputDir);

} else {
if (SystemUtils.IS_OS_LINUX) {
noPIE = detectNoPIE();
}

Optional<String> graal = nativeConfig.graalvmHome;
File java = nativeConfig.javaHome;
if (graal.isPresent()) {
env.put(GRAALVM_HOME, graal.get());
}
if (java == null) {
// try system property first - it will be the JAVA_HOME used by the current JVM
String home = System.getProperty(JAVA_HOME_SYS);
if (home == null) {
// No luck, somewhat a odd JVM not enforcing this property
// try with the JAVA_HOME environment variable
home = env.get(JAVA_HOME_ENV);
}

if (home != null) {
java = new File(home);
}
}
nativeImage = getNativeImageExecutable(graal, java, env, nativeConfig, processInheritIODisabled, outputDir);
if (!isContainerBuild && SystemUtils.IS_OS_LINUX) {
noPIE = detectNoPIE();
}

final GraalVM.Version graalVMVersion;

try {
List<String> versionCommand = new ArrayList<>(nativeImage);
versionCommand.add("--version");

Process versionProcess = new ProcessBuilder(versionCommand.toArray(new String[0]))
.redirectErrorStream(true)
.start();
versionProcess.waitFor();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(versionProcess.getInputStream(), StandardCharsets.UTF_8))) {
graalVMVersion = GraalVM.Version.of(reader.lines());
}
} catch (Exception e) {
throw new RuntimeException("Failed to get GraalVM version", e);
}
nativeImage = getNativeImage(nativeConfig, processInheritIODisabled, outputDir, env);
final GraalVM.Version graalVMVersion = GraalVM.Version.ofBinary(nativeImage);

if (graalVMVersion.isDetected()) {
checkGraalVMVersion(graalVMVersion);
Expand Down Expand Up @@ -341,6 +301,35 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa
}
}

private static List<String> getNativeImage(NativeConfig nativeConfig,
Optional<ProcessInheritIODisabled> processInheritIODisabled,
Path outputDir, Map<String, String> env) {
boolean isContainerBuild = nativeConfig.containerRuntime.isPresent() || nativeConfig.containerBuild;
if (isContainerBuild) {
return setupContainerBuild(nativeConfig, processInheritIODisabled, outputDir);
} else {
Optional<String> graal = nativeConfig.graalvmHome;
File java = nativeConfig.javaHome;
if (graal.isPresent()) {
env.put(GRAALVM_HOME, graal.get());
}
if (java == null) {
// try system property first - it will be the JAVA_HOME used by the current JVM
String home = System.getProperty(JAVA_HOME_SYS);
if (home == null) {
// No luck, somewhat a odd JVM not enforcing this property
// try with the JAVA_HOME environment variable
home = env.get(JAVA_HOME_ENV);
}

if (home != null) {
java = new File(home);
}
}
return getNativeImageExecutable(graal, java, env, nativeConfig, processInheritIODisabled, outputDir);
}
}

public static List<String> setupContainerBuild(NativeConfig nativeConfig,
Optional<ProcessInheritIODisabled> processInheritIODisabled, Path outputDir) {
List<String> nativeImage;
Expand Down Expand Up @@ -688,8 +677,17 @@ private static void objcopy(String... args) {

//https://github.com/quarkusio/quarkus/issues/11573
//https://github.com/oracle/graal/issues/1610
@BuildStep
List<RuntimeReinitializedClassBuildItem> graalVmWorkaround() {
List<RuntimeReinitializedClassBuildItem> graalVmWorkaround(NativeConfig nativeConfig,
NativeImageSourceJarBuildItem nativeImageSourceJarBuildItem,
Optional<ProcessInheritIODisabled> processInheritIODisabled) {
Path outputDir = nativeImageSourceJarBuildItem.getPath().getParent();
HashMap<String, String> env = new HashMap<>(System.getenv());
List<String> nativeImage = getNativeImage(nativeConfig, processInheritIODisabled, outputDir, env);
GraalVM.Version version = GraalVM.Version.ofBinary(nativeImage);
if (version.isNewerThan(GraalVM.Version.VERSION_20_2)) {
// https://github.com/oracle/graal/issues/2841
return Collections.emptyList();
}
return Arrays.asList(new RuntimeReinitializedClassBuildItem(ThreadLocalRandom.class.getName()),
new RuntimeReinitializedClassBuildItem("java.lang.Math$RandomNumberGeneratorHolder"));
}
Expand Down Expand Up @@ -785,6 +783,26 @@ static Version of(Stream<String> lines) {
return UNVERSIONED;
}

private static Version ofBinary(List<String> nativeImage) {
final Version graalVMVersion;
try {
List<String> versionCommand = new ArrayList<>(nativeImage);
versionCommand.add("--version");

Process versionProcess = new ProcessBuilder(versionCommand.toArray(new String[0]))
.redirectErrorStream(true)
.start();
versionProcess.waitFor();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(versionProcess.getInputStream(), StandardCharsets.UTF_8))) {
graalVMVersion = of(reader.lines());
}
} catch (Exception e) {
throw new RuntimeException("Failed to get GraalVM version", e);
}
return graalVMVersion;
}

private static boolean isSnapshot(String s) {
return s == null;
}
Expand Down

0 comments on commit 51a6f7d

Please sign in to comment.