From 26f13d83d5406d1096dbedfeecf9c6b632dda82c Mon Sep 17 00:00:00 2001 From: Gunnar Morling Date: Thu, 14 Oct 2021 12:32:52 +0200 Subject: [PATCH] DBZ-3993 Reflectively invoking Runtime.version(); As that API is only available from Java 9 onwards, calling it will cause a compilation failure when compiling with --release. --- .../java/io/debezium/util/JvmVersionUtil.java | 53 +++++++++++++++++-- pom.xml | 3 ++ 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/debezium-core/src/main/java/io/debezium/util/JvmVersionUtil.java b/debezium-core/src/main/java/io/debezium/util/JvmVersionUtil.java index 7330dc63d..4b2a4ac4f 100644 --- a/debezium-core/src/main/java/io/debezium/util/JvmVersionUtil.java +++ b/debezium-core/src/main/java/io/debezium/util/JvmVersionUtil.java @@ -5,6 +5,17 @@ */ package io.debezium.util; +import static java.lang.invoke.MethodType.methodType; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import io.debezium.DebeziumException; + /** * Utility class dealing with Java version information. * @@ -12,20 +23,52 @@ */ public class JvmVersionUtil { + private static final Logger LOGGER = LoggerFactory.getLogger(JvmVersionUtil.class); + private static final int FEATURE_VERSION = determineFeatureVersion(); + private JvmVersionUtil() { } /** * Returns the feature version of the current JVM, e.g. 8 or 17. */ - public static int getFeatureVersion() { + private static int determineFeatureVersion() { + int featureVersion; + + // Trying Runtime.version().version().get(0) at first; this will return the major version on Java 9+ + // + // Using method handles so to be able to compile this code to Java 1.8 byte code level using the --release + // parameter + // + // Using the List version() approach, so to avoid calling the deprecated majorVersion() method try { - return Runtime.version().feature(); + ClassLoader classLoader = JvmVersionUtil.class.getClassLoader(); + + Class versionClass = classLoader.loadClass("java.lang.Runtime$Version"); + MethodHandle versionHandle = MethodHandles.lookup().findStatic(Runtime.class, "version", methodType(versionClass)); + MethodHandle versionListHandle = MethodHandles.lookup().findVirtual(versionClass, "version", methodType(List.class)); + + try { + Object version = versionHandle.invoke(); + List versions = (List) versionListHandle.bindTo(version).invoke(); + featureVersion = versions.get(0); + } + catch (Throwable e) { + throw new DebeziumException("Couldn't determine runtime version", e); + } } - // The version() is only available on Java 9 and later - catch (NoSuchMethodError nsme) { + // The version() method is only available on Java 9 and later + catch (ClassNotFoundException | NoSuchMethodError | NoSuchMethodException | IllegalAccessException nsme) { final String specVersion = System.getProperty("java.specification.version"); - return Integer.parseInt(specVersion.substring(specVersion.indexOf('.') + 1)); + featureVersion = Integer.parseInt(specVersion.substring(specVersion.indexOf('.') + 1)); } + + LOGGER.debug("Determined Java version: {}", featureVersion); + + return featureVersion; + } + + public static int getFeatureVersion() { + return FEATURE_VERSION; } } diff --git a/pom.xml b/pom.xml index 1e0a36fb8..fd8e49af9 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,9 @@ UTF-8 UTF-8 + 1.8 1.8