Skip to content

Commit

Permalink
Support graal jdk automanagement installations (#497)
Browse files Browse the repository at this point in the history
Support graal jdk automanagement installations
  • Loading branch information
crogoz authored Jan 30, 2025
1 parent 2384e2e commit b642b09
Show file tree
Hide file tree
Showing 9 changed files with 125 additions and 86 deletions.
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-497.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: improvement
improvement:
description: Support graal jdk automanagement installations
links:
- https://github.com/palantir/gradle-jdks/pull/497
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
import com.palantir.gradle.jdks.AmazonCorrettoJdkDistribution;
import com.palantir.gradle.jdks.GraalVmCeDistribution;
import com.palantir.gradle.jdks.JdkPath;
import com.palantir.gradle.jdks.JdkRelease;
import com.palantir.gradle.jdks.setup.common.Arch;
Expand All @@ -42,37 +43,39 @@
public class GradleJdkInstallationSetupIntegrationTest {

private static final String JDK_VERSION = "11.0.21.9.1";
private static final String GRAAL_VERSION = "23.0.1";
private static final Arch ARCH = CurrentArch.get();
private static final String CORRETTO_DISTRIBUTION_URL_ENV = "CORRETTO_DISTRIBUTION_URL";
private static final AmazonCorrettoJdkDistribution CORRETTO_JDK_DISTRIBUTION = new AmazonCorrettoJdkDistribution();
private static final GraalVmCeDistribution GRAAL_VM_CE_DISTRIBUTION = new GraalVmCeDistribution();
private static final boolean DO_NOT_INSTALL_CURL = false;
private static final boolean INSTALL_CURL = true;

@TempDir
private Path workingDir;

@Test
public void can_setup_jdks_centos() throws IOException, InterruptedException {
public void can_setup_jdks_centos_using_wget() throws IOException, InterruptedException {
setupGradleDirectoryStructure(Os.LINUX_GLIBC);
dockerBuildAndRunTestingScript("centos:7", "/bin/bash", DO_NOT_INSTALL_CURL, false);
dockerBuildAndRunTestingScript("centos:7", "/bin/bash", DO_NOT_INSTALL_CURL, false, true);
}

@Test
public void can_setup_jdks_ubuntu() throws IOException, InterruptedException {
public void can_setup_jdks_ubuntu_using_curl() throws IOException, InterruptedException {
setupGradleDirectoryStructure(Os.LINUX_GLIBC);
dockerBuildAndRunTestingScript("ubuntu:20.04", "/bin/bash", INSTALL_CURL, false);
dockerBuildAndRunTestingScript("ubuntu:20.04", "/bin/bash", INSTALL_CURL, false, true);
}

@Test
public void can_reinstall_jdks_ubuntu() throws IOException, InterruptedException {
public void can_reinstall_jdks_ubuntu_using_curl() throws IOException, InterruptedException {
setupGradleDirectoryStructure(Os.LINUX_GLIBC);
dockerBuildAndRunTestingScript("ubuntu:20.04", "/bin/bash", INSTALL_CURL, true);
dockerBuildAndRunTestingScript("ubuntu:20.04", "/bin/bash", INSTALL_CURL, true, true);
}

@Test
public void can_setup_jdks_alpine() throws IOException, InterruptedException {
setupGradleDirectoryStructure(Os.LINUX_MUSL);
dockerBuildAndRunTestingScript("alpine:3.16.0", "/bin/sh", DO_NOT_INSTALL_CURL, false);
dockerBuildAndRunTestingScript("alpine:3.16.0", "/bin/sh", DO_NOT_INSTALL_CURL, false, false);
}

private Path setupGradleDirectoryStructure(Os os) throws IOException {
Expand All @@ -97,8 +100,7 @@ private Path setupGradleDirectoryStructure(Os os) throws IOException {
* ├── subProjects/...
* ...
*/
String jdkMajorVersion =
Iterables.get(Splitter.on('.').split(GradleJdkInstallationSetupIntegrationTest.JDK_VERSION), 0);
String jdkMajorVersion = Iterables.get(Splitter.on('.').split(JDK_VERSION), 0);
Path gradleDirectory = Files.createDirectories(workingDir.resolve("gradle"));
Path gradleJdkVersion = Files.createFile(gradleDirectory.resolve("gradle-daemon-jdk-version"));
writeFileContent(gradleJdkVersion, jdkMajorVersion);
Expand All @@ -109,6 +111,8 @@ private Path setupGradleDirectoryStructure(Os os) throws IOException {
.build());
Path archDirectory = Files.createDirectories(
gradleDirectory.resolve(String.format("jdks/%s/%s/%s", jdkMajorVersion, os.uiName(), ARCH.uiName())));

// Adding an Amazon Corretto distribution
Path downloadUrlPath = Files.createFile(archDirectory.resolve("download-url"));
String correttoDistributionUrl = Optional.ofNullable(System.getenv(CORRETTO_DISTRIBUTION_URL_ENV))
.orElseGet(CORRETTO_JDK_DISTRIBUTION::defaultBaseUrl);
Expand All @@ -117,9 +121,29 @@ private Path setupGradleDirectoryStructure(Os os) throws IOException {
String.format(
String.format("%s/%s.%s", correttoDistributionUrl, jdkPath.filename(), jdkPath.extension())));
Path localPath = Files.createFile(archDirectory.resolve("local-path"));
writeFileContent(
localPath, String.format("amazon-corretto-%s", GradleJdkInstallationSetupIntegrationTest.JDK_VERSION));

writeFileContent(localPath, String.format("amazon-corretto-%s", JDK_VERSION));

if (!os.equals(Os.LINUX_MUSL)) {
// Adding a GraalVm distribution only for non-musl
String graalMajorVersion = Iterables.get(Splitter.on('.').split(GRAAL_VERSION), 0);
Path graalDirectory = Files.createDirectories(gradleDirectory.resolve(
String.format("jdks/%s/%s/%s", graalMajorVersion, os.uiName(), ARCH.uiName())));
Path graalDownloadUrlPath = Files.createFile(graalDirectory.resolve("download-url"));
JdkPath graalJdkPath = GRAAL_VM_CE_DISTRIBUTION.path(JdkRelease.builder()
.version(GRAAL_VERSION)
.os(os)
.arch(ARCH)
.build());
writeFileContent(
graalDownloadUrlPath,
String.format(String.format(
"%s/%s.%s",
GRAAL_VM_CE_DISTRIBUTION.defaultBaseUrl(),
graalJdkPath.filename(),
graalJdkPath.extension())));
Path graalLocalPath = Files.createFile(graalDirectory.resolve("local-path"));
writeFileContent(graalLocalPath, String.format("graalvm-community-jdk-%s", GRAAL_VERSION));
}
// copy the jar from build/libs to the gradle directory
Files.copy(
Path.of(String.format(
Expand Down Expand Up @@ -158,7 +182,8 @@ private static void writeFileContent(Path path, String content) throws IOExcepti
Files.writeString(path, content + "\n");
}

private void dockerBuildAndRunTestingScript(String baseImage, String shell, boolean installCurl, boolean addJdkDir)
private void dockerBuildAndRunTestingScript(
String baseImage, String shell, boolean installCurl, boolean addJdkDir, boolean expectedGraalJdk)
throws IOException, InterruptedException {
Path dockerFile = Path.of("src/integrationTest/resources/template.Dockerfile");
String dockerImage = String.format("jdk-test-%s", baseImage);
Expand All @@ -178,12 +203,17 @@ private void dockerBuildAndRunTestingScript(String baseImage, String shell, bool
"-f",
dockerFile.toAbsolutePath().toString(),
workingDir.toAbsolutePath().toString()));

assertThat(runCommandWithZeroExitCode(
List.of("docker", "run", "--rm", dockerImage, shell, "/testing-script.sh")))
String output =
runCommandWithZeroExitCode(List.of("docker", "run", "--rm", dockerImage, shell, "/testing-script.sh"));
assertThat(output)
.contains("openjdk version \"11.0.21\"")
.contains("JAVA_HOME is set to: /root/.gradle/gradle-jdks/amazon-corretto-11.0.21.9.1")
.doesNotContain("Unexpected output");
if (expectedGraalJdk) {
assertThat(output).contains("GraalVM CE 23.0.1");
} else {
assertThat(output).contains("GraalVM is not set");
}
}

private static String runCommandWithZeroExitCode(List<String> commandArguments)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ echo "JAVA_HOME is set to: $JAVA_HOME"
if [ -s /tmp/all-output ]; then
echo "Unexpected output after all JDKs were installed: $(cat /tmp/all-output)"
fi

if [ ! -f /root/.gradle/gradle-jdks/graalvm-community-jdk-23.0.1/bin/java ]; then
echo "GraalVM is not set"
else
/root/.gradle/gradle-jdks/graalvm-community-jdk-23.0.1/bin/java -version
fi
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,8 @@
import java.util.Properties;

/**
* Class responsible for 2 workflows:
* 1. installing the current JDK into {@code destinationJdkInstallationDir} and importing the
* system certificates into the JDK's truststore.
* 2. setting the java.home value in .gradle/config.properties to {@code gradleDaemonJavaHome} in the project directory.
* The class will be called by the Gradle setup script in
* Class responsible for installing the current JDK into {@code destinationJdkInstallationDir} and importing the
* system certificates into the JDK's truststore. The class will be called by the Gradle setup script in
* <a href="file:../resources/gradle-jdks-setup.sh">resources/gradle-jdks-setup.sh</a>.
*/
public final class GradleJdkInstallationSetup {
Expand Down Expand Up @@ -131,7 +128,7 @@ private static boolean copy(ILogger logger, Path destinationJdkInstallationDirec
logger.log(
String.format("Copying JDK from %s into %s", currentJavaHome, destinationJdkInstallationDirectory));

// same filesystem for the temporary diretory as the destinationDirectory to ensure an atomic move
// same filesystem for the temporary directory as the destinationDirectory to ensure an atomic move
Path tempCopyDir = jdksInstallationDirectory.resolve(
String.format("tmp-%s", destinationJdkInstallationDirectory.getFileName()));
// Ensuring that the JDK installation directory won't be partially copied.
Expand Down
4 changes: 2 additions & 2 deletions gradle-jdks-setup/src/main/resources/gradle-jdks-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,11 @@ install_and_setup_jdks() {
case "$distribution_url" in
*.zip)
distribution_name=${distribution_url##*/}
curl -C - "$distribution_url" -o "$distribution_name"
curl -L -C - "$distribution_url" -o "$distribution_name"
tar -xzf "$distribution_name"
;;
*)
curl -C - "$distribution_url" | tar -xzf -
curl -L -C - "$distribution_url" | tar -xzf -
;;
esac
elif command -v wget > /dev/null 2>&1; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,21 @@

package com.palantir.gradle.jdks;

import com.google.common.annotations.VisibleForTesting;
import com.palantir.gradle.jdks.JdkPath.Extension;
import com.palantir.gradle.jdks.setup.common.Arch;
import com.palantir.gradle.jdks.setup.common.Os;
import org.immutables.value.Value;

final class GraalVmCeDistribution implements JdkDistribution {
public final class GraalVmCeDistribution implements JdkDistribution {
@Override
public String defaultBaseUrl() {
return "https://github.com/graalvm/graalvm-ce-builds/releases/download";
}

@Override
public JdkPath path(JdkRelease jdkRelease) {
GraalVersionSplit splitVersion = splitVersion(jdkRelease.version());

String filename = String.format(
"vm-%s/graalvm-ce-java%s-%s-%s-%s",
splitVersion.graalVersion(),
splitVersion.javaVersion(),
os(jdkRelease.os()),
arch(jdkRelease.arch()),
splitVersion.graalVersion());
"jdk-%s/graalvm-community-jdk-%s_%s-%s_bin",
jdkRelease.version(), jdkRelease.version(), os(jdkRelease.os()), arch(jdkRelease.arch()));

return JdkPath.builder()
.filename(filename)
Expand All @@ -49,8 +41,9 @@ public JdkPath path(JdkRelease jdkRelease) {
private static String os(Os os) {
switch (os) {
case MACOS:
return "darwin";
return "macos";
case LINUX_GLIBC:
case LINUX_MUSL:
return "linux";
case WINDOWS:
return "windows";
Expand All @@ -61,8 +54,9 @@ private static String os(Os os) {

private static String arch(Arch arch) {
switch (arch) {
case X86:
case X86_64:
return "amd64";
return "x64";
case AARCH64:
return "aarch64";
default:
Expand All @@ -73,6 +67,7 @@ private static String arch(Arch arch) {
private static Extension extension(Os operatingSystem) {
switch (operatingSystem) {
case LINUX_GLIBC:
case LINUX_MUSL:
case MACOS:
return Extension.TARGZ;
case WINDOWS:
Expand All @@ -81,35 +76,4 @@ private static Extension extension(Os operatingSystem) {
throw new UnsupportedOperationException("Unknown OS: " + operatingSystem);
}
}

@VisibleForTesting
static GraalVersionSplit splitVersion(String combinedVersion) {
int splitIndex = combinedVersion.indexOf(".");

if (splitIndex == -1) {
throw new IllegalArgumentException(String.format(
"Expected %s to at least contain one dot separating the java version from graal version. "
+ "Expected Format `javaVersion.graalVersion` (e.g. 17.21.2.0 -> Java Version: 17, "
+ "Graal Version: 21.2.0)",
combinedVersion));
}

return GraalVersionSplit.builder()
.graalVersion(combinedVersion.substring(splitIndex + 1))
.javaVersion(combinedVersion.substring(0, splitIndex))
.build();
}

@Value.Immutable
interface GraalVersionSplit {
String graalVersion();

String javaVersion();

static Builder builder() {
return new Builder();
}

class Builder extends ImmutableGraalVersionSplit.Builder {}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import static org.assertj.core.api.Assertions.assertThat;

import com.palantir.gradle.jdks.GraalVmCeDistribution.GraalVersionSplit;
import com.palantir.gradle.jdks.JdkPath.Extension;
import com.palantir.gradle.jdks.setup.common.Arch;
import com.palantir.gradle.jdks.setup.common.Os;
Expand All @@ -27,21 +26,14 @@
class GraalVmCeDistributionTest {

@Test
void graalvm_ce_version_splits_version() {
GraalVersionSplit versionSplit = GraalVmCeDistribution.splitVersion("17.23.2.0");
assertThat(versionSplit.javaVersion()).isEqualTo("17");
assertThat(versionSplit.graalVersion()).isEqualTo("23.2.0");
}

@Test
void jdk_path_linux_x86_64() {
void jdk_path_linux_aarch64() {
GraalVmCeDistribution distribution = new GraalVmCeDistribution();
JdkPath path = distribution.path(JdkRelease.builder()
.arch(Arch.X86_64)
.arch(Arch.AARCH64)
.os(Os.LINUX_GLIBC)
.version("17.22.3.0")
.version("23.0.2")
.build());
assertThat(path.filename()).isEqualTo("vm-22.3.0/graalvm-ce-java17-linux-amd64-22.3.0");
assertThat(path.filename()).isEqualTo("jdk-23.0.2/graalvm-community-jdk-23.0.2_linux-aarch64_bin");
assertThat(path.extension()).isEqualTo(Extension.TARGZ);
}

Expand All @@ -51,9 +43,9 @@ void jdk_path_macosx() {
JdkPath path = distribution.path(JdkRelease.builder()
.arch(Arch.AARCH64)
.os(Os.MACOS)
.version("19.22.3.0")
.version("23.0.2")
.build());
assertThat(path.filename()).isEqualTo("vm-22.3.0/graalvm-ce-java19-darwin-aarch64-22.3.0");
assertThat(path.filename()).isEqualTo("jdk-23.0.2/graalvm-community-jdk-23.0.2_macos-aarch64_bin");
assertThat(path.extension()).isEqualTo(Extension.TARGZ);
}

Expand All @@ -63,9 +55,9 @@ void jdk_path_windows_x86_64() {
JdkPath path = distribution.path(JdkRelease.builder()
.arch(Arch.X86_64)
.os(Os.WINDOWS)
.version("11.20.3.6")
.version("23.0.2")
.build());
assertThat(path.filename()).isEqualTo("vm-20.3.6/graalvm-ce-java11-windows-amd64-20.3.6");
assertThat(path.filename()).isEqualTo("jdk-23.0.2/graalvm-community-jdk-23.0.2_windows-x64_bin");
assertThat(path.extension()).isEqualTo(Extension.ZIP);
}
}
Loading

0 comments on commit b642b09

Please sign in to comment.