From 930ce4933277cfb64d54ae8333951c3662d11d51 Mon Sep 17 00:00:00 2001 From: Chetan Gudisagar Date: Mon, 14 Apr 2025 17:32:00 -0700 Subject: [PATCH] Revert "Migrate to JDK 21 (#279)" This reverts commit 2a17efa298fe9df781e050c58495cac27e21561c. --- .github/workflows/corfu-client-example.yml | 6 +- .github/workflows/publish-cloud.yml | 2 +- .../workflows/publish-injection-framework.yml | 2 +- .../workflows/publish-universe-artifacts.yml | 6 +- .github/workflows/pull_request_benchmarks.yml | 6 +- .github/workflows/pull_request_universe.yml | 6 +- .../workflows/run-corfu-cloud-deployment.yml | 2 +- .github/workflows/run_benchmarks.yml | 6 +- benchmarks/Dockerfile | 2 +- cloud/corfu/corfu-client-example/Dockerfile | 2 +- .../kibana/kibana-tools/Dockerfile | 2 +- gradle/idea-project.gradle.kts | 2 +- gradle/jacoco.gradle | 2 +- gradle/java.gradle | 4 +- tests/Dockerfile | 2 +- .../docker/universe/FakeDns.java | 145 +++++++++++++++--- 16 files changed, 146 insertions(+), 51 deletions(-) diff --git a/.github/workflows/corfu-client-example.yml b/.github/workflows/corfu-client-example.yml index eeeb47f1..5df5f879 100644 --- a/.github/workflows/corfu-client-example.yml +++ b/.github/workflows/corfu-client-example.yml @@ -11,13 +11,13 @@ jobs: PUBLISH_TOKEN: ${{ secrets.publish_token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v3 - name: Setup BuildX - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v2 - name: Login to the Registry - uses: docker/login-action@v3 + uses: docker/login-action@v2 with: username: ${{secrets.DOCKER_USER_NAME}} password: ${{secrets.DOCKER_PASSWORD}} diff --git a/.github/workflows/publish-cloud.yml b/.github/workflows/publish-cloud.yml index 5feed702..595201ab 100644 --- a/.github/workflows/publish-cloud.yml +++ b/.github/workflows/publish-cloud.yml @@ -18,7 +18,7 @@ jobs: if: github.event_name == 'push' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - uses: satackey/action-docker-layer-caching@v0.0.8 continue-on-error: true diff --git a/.github/workflows/publish-injection-framework.yml b/.github/workflows/publish-injection-framework.yml index 683e34e7..f147d513 100644 --- a/.github/workflows/publish-injection-framework.yml +++ b/.github/workflows/publish-injection-framework.yml @@ -18,7 +18,7 @@ jobs: if: github.event_name == 'push' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - uses: satackey/action-docker-layer-caching@v0.0.8 continue-on-error: true diff --git a/.github/workflows/publish-universe-artifacts.yml b/.github/workflows/publish-universe-artifacts.yml index 4abf01dd..5149e854 100644 --- a/.github/workflows/publish-universe-artifacts.yml +++ b/.github/workflows/publish-universe-artifacts.yml @@ -20,18 +20,18 @@ jobs: PUBLISH_TOKEN: ${{ secrets.publish_token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'corretto' - java-version: '21' + java-version: '17' check-latest: true cache-dependency-path: '**/pom.xml' - name: Cache local Gradle repository - uses: actions/cache@v4 + uses: actions/cache@v2 with: path: | ~/.gradle/caches diff --git a/.github/workflows/pull_request_benchmarks.yml b/.github/workflows/pull_request_benchmarks.yml index 99bccd15..7a1eadcb 100644 --- a/.github/workflows/pull_request_benchmarks.yml +++ b/.github/workflows/pull_request_benchmarks.yml @@ -16,18 +16,18 @@ jobs: PUBLISH_TOKEN: ${{ secrets.publish_token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'corretto' - java-version: '21' + java-version: '17' check-latest: true cache-dependency-path: '**/pom.xml' - name: Cache local Gradle repository - uses: actions/cache@v4 + uses: actions/cache@v2 with: path: | ~/.gradle/caches diff --git a/.github/workflows/pull_request_universe.yml b/.github/workflows/pull_request_universe.yml index 260762e1..93f03a4f 100644 --- a/.github/workflows/pull_request_universe.yml +++ b/.github/workflows/pull_request_universe.yml @@ -17,18 +17,18 @@ jobs: PUBLISH_TOKEN: ${{ secrets.publish_token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'corretto' - java-version: '21' + java-version: '17' check-latest: true cache-dependency-path: '**/pom.xml' - name: Cache local Gradle repository - uses: actions/cache@v4 + uses: actions/cache@v2 with: path: | ~/.gradle/caches diff --git a/.github/workflows/run-corfu-cloud-deployment.yml b/.github/workflows/run-corfu-cloud-deployment.yml index a6d6dd43..b267bcb9 100644 --- a/.github/workflows/run-corfu-cloud-deployment.yml +++ b/.github/workflows/run-corfu-cloud-deployment.yml @@ -7,7 +7,7 @@ jobs: corfu-helm-deployment: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - uses: satackey/action-docker-layer-caching@v0.0.8 continue-on-error: true diff --git a/.github/workflows/run_benchmarks.yml b/.github/workflows/run_benchmarks.yml index 79fab77e..a086895b 100644 --- a/.github/workflows/run_benchmarks.yml +++ b/.github/workflows/run_benchmarks.yml @@ -19,18 +19,18 @@ jobs: PUBLISH_TOKEN: ${{ secrets.publish_token }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v2 - name: Set up JDK uses: actions/setup-java@v4 with: distribution: 'corretto' - java-version: '21' + java-version: '17' check-latest: true cache-dependency-path: '**/pom.xml' - name: Cache local Gradle repository - uses: actions/cache@v4 + uses: actions/cache@v2 with: path: | ~/.gradle/caches diff --git a/benchmarks/Dockerfile b/benchmarks/Dockerfile index 44e8c645..c63136aa 100644 --- a/benchmarks/Dockerfile +++ b/benchmarks/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:21-bullseye +FROM openjdk:8-jdk-bullseye RUN apt-get update && apt-get install -y iputils-ping diff --git a/cloud/corfu/corfu-client-example/Dockerfile b/cloud/corfu/corfu-client-example/Dockerfile index 1aa336c0..fa2bb249 100644 --- a/cloud/corfu/corfu-client-example/Dockerfile +++ b/cloud/corfu/corfu-client-example/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:21-bullseye +FROM openjdk:8-jdk-alpine3.8 ADD ./build/libs/corfu-runtime-client-example.jar /app/ diff --git a/cloud/infrastructure/kibana/kibana-tools/Dockerfile b/cloud/infrastructure/kibana/kibana-tools/Dockerfile index 6f484616..85bfe5ec 100644 --- a/cloud/infrastructure/kibana/kibana-tools/Dockerfile +++ b/cloud/infrastructure/kibana/kibana-tools/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:21-bullseye +FROM openjdk:8-jdk-alpine3.8 ADD ./lib /app/lib/ ADD ./*.jar /app/ diff --git a/gradle/idea-project.gradle.kts b/gradle/idea-project.gradle.kts index e77cc612..af89f295 100644 --- a/gradle/idea-project.gradle.kts +++ b/gradle/idea-project.gradle.kts @@ -8,7 +8,7 @@ idea.project { // can be used. E.g. Subversion, Mercurial. vcs = "Git" - setLanguageLevel("21") + setLanguageLevel("1.8") } idea.module { diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index 636cf225..f6b618a3 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -1,6 +1,6 @@ jacoco { - toolVersion = "0.8.13" + toolVersion = "0.8.12" } jacocoTestReport { diff --git a/gradle/java.gradle b/gradle/java.gradle index cac668d1..b64cf74f 100644 --- a/gradle/java.gradle +++ b/gradle/java.gradle @@ -1,8 +1,8 @@ group = 'org.corfudb' java { - sourceCompatibility = JavaVersion.VERSION_21 - targetCompatibility = JavaVersion.VERSION_21 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 withJavadocJar() withSourcesJar() diff --git a/tests/Dockerfile b/tests/Dockerfile index cd3abba0..7af1f1db 100644 --- a/tests/Dockerfile +++ b/tests/Dockerfile @@ -1,4 +1,4 @@ -FROM openjdk:21-bullseye +FROM openjdk:8u212-jdk ADD ./ /universe-tests WORKDIR /universe-tests/tests diff --git a/universe/universe-core/src/main/java/org/corfudb/universe/infrastructure/docker/universe/FakeDns.java b/universe/universe-core/src/main/java/org/corfudb/universe/infrastructure/docker/universe/FakeDns.java index c0ff4454..ad1e93df 100644 --- a/universe/universe-core/src/main/java/org/corfudb/universe/infrastructure/docker/universe/FakeDns.java +++ b/universe/universe-core/src/main/java/org/corfudb/universe/infrastructure/docker/universe/FakeDns.java @@ -1,14 +1,21 @@ package org.corfudb.universe.infrastructure.docker.universe; +import com.google.common.base.Throwables; +import com.google.common.net.InetAddresses; import lombok.extern.slf4j.Slf4j; import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; import java.net.InetAddress; import java.net.UnknownHostException; -import java.net.spi.InetAddressResolver; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import java.util.stream.Stream; +import java.util.NoSuchElementException; + /** * Fake DNS resolver which allows our tests to work well even though we use * strange loopback IP addresses (127.x.y.z) with no corresponding reverse @@ -26,8 +33,11 @@ @Slf4j public class FakeDns { private static final FakeDns instance = new FakeDns(); + private final Map forwardResolutions = new HashMap<>(); + private final Map reverseResolutions = new HashMap<>(); + /** * whether the fake resolver has been installed */ @@ -40,19 +50,22 @@ public static FakeDns getInstance() { return instance; } - public synchronized FakeDns addForwardResolution(String hostname, InetAddress ip) { + public synchronized void addForwardResolution(String hostname, InetAddress ip) { + log.info("Add forward resolution. Hostname: {}, ip: {}", hostname, ip); forwardResolutions.put(hostname, ip); - return this; } /** * Install the fake DNS resolver into the Java runtime. */ public synchronized FakeDns install() { - if (installed) return this; + if (installed) { + return this; + } try { installDns(); } catch (Exception e) { + log.error("FakeDns initialization error", e); throw new IllegalStateException(e); } installed = true; @@ -60,34 +73,116 @@ public synchronized FakeDns install() { return this; } - public class CorfuResolver implements InetAddressResolver { + private void installDns() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, + ClassNotFoundException, NoSuchFieldException { + try { + // Override the NameService in Java 9 or later. + final Class nameServiceInterface = Class.forName("java.net.InetAddress$NameService"); + Field field = InetAddress.class.getDeclaredField("nameService"); + // Get the default NameService to fallback to. + Method method = InetAddress.class.getDeclaredMethod("createNameService"); + method.setAccessible(true); + Object fallbackNameService = method.invoke(null); + // Create a proxy instance to set on the InetAddress field which will handle + // all NameService calls. + Object proxy = Proxy.newProxyInstance( + nameServiceInterface.getClassLoader(), + new Class[]{nameServiceInterface}, + new NameServiceListener(fallbackNameService) + ); + field.setAccessible(true); + field.set(InetAddress.class, proxy); + } catch (ClassNotFoundException | NoSuchFieldException e) { + // Override the NameService in Java 8 or earlier. + final Class nameServiceInterface = Class.forName("sun.net.spi.nameservice.NameService"); + Field field = InetAddress.class.getDeclaredField("nameServices"); + // Get the default NameService to fallback to. + Method method = InetAddress.class.getDeclaredMethod("createNSProvider", String.class); + method.setAccessible(true); + Object fallbackNameService = method.invoke(null, "default"); + // Create a proxy instance to set on the InetAddress field which will handle + // all NameService calls. + Object proxy = Proxy.newProxyInstance( + nameServiceInterface.getClassLoader(), + new Class[]{nameServiceInterface}, + new NameServiceListener(fallbackNameService) + ); + field.setAccessible(true); + // Java 8 or earlier takes a list of NameServices + field.set(InetAddress.class, Arrays.asList(proxy)); + } + } + + /** + * The NameService in all versions of Java has the same interface, so we + * can use the same InvocationHandler as our proxy instance for both + * java.net.InetAddress$NameService and sun.net.spi.nameservice.NameService. + */ + private class NameServiceListener implements InvocationHandler { - private final InetAddressResolver defaultResolver; + private final Object fallbackNameService; - public CorfuResolver(InetAddressResolver defaultResolver) { - this.defaultResolver = defaultResolver; + // Creates a NameServiceListener with a NameService implementation to + // fallback to. The parameter is untyped so we can handle the NameService + // type in all versions of Java with reflection. + NameServiceListener(Object fallbackNameService) { + this.fallbackNameService = fallbackNameService; } - @Override - public Stream lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException { - if (forwardResolutions.containsKey(host)) { - return Stream.of(forwardResolutions.get(host)); - } else { - return defaultResolver.lookupByName(host, lookupPolicy); + private InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { + InetAddress inetAddress; + synchronized (FakeDns.this) { + inetAddress = forwardResolutions.get(host); + } + if (inetAddress != null) { + return new InetAddress[]{inetAddress}; } - } - @Override - public String lookupByAddress(byte[] addr) throws UnknownHostException { - return defaultResolver.lookupByAddress(addr); + try { + Method method = fallbackNameService.getClass().getDeclaredMethod("lookupAllHostAddr", String.class); + method.setAccessible(true); + return (InetAddress[]) method.invoke(fallbackNameService, host); + } catch (ReflectiveOperationException | NoSuchElementException | SecurityException e) { + throw new AssertionError("unexpected reflection issue", e); + } } - } - private void installDns() throws IllegalAccessException, NoSuchFieldException { - Field resolverField = InetAddress.class.getDeclaredField("resolver"); - resolverField.setAccessible(true); + private String getHostByAddr(byte[] addr) throws UnknownHostException { + if (addr[0] == 127) { + return InetAddresses.toAddrString(InetAddress.getByAddress(addr)); + } + + String hostname; + synchronized (FakeDns.this) { + hostname = reverseResolutions.get(InetAddress.getByAddress(addr)); + } + if (hostname != null) { + return hostname; + } + + try { + Method method = fallbackNameService + .getClass() + .getDeclaredMethod("getHostByAddr", byte[].class); + + method.setAccessible(true); + return (String) method.invoke(fallbackNameService, (Object) addr); + } catch (ReflectiveOperationException | NoSuchElementException | SecurityException e) { + Throwables.propagateIfPossible(e.getCause(), UnknownHostException.class); + throw new AssertionError("unexpected reflection issue", e); + } + } - var defaultResolver = (InetAddressResolver) resolverField.get(InetAddress.class); - resolverField.set(InetAddressResolver.class, new CorfuResolver(defaultResolver)); + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "lookupAllHostAddr": + return lookupAllHostAddr((String) args[0]); + case "getHostByAddr": + return getHostByAddr((byte[]) args[0]); + default: + throw new UnsupportedOperationException(); + } + } } }