Browse Source

Use multi-release-jar for java version checker (#85767)

The java version checker tests whether the current jdk is a sufficient
version to run Elasticsearch. Since it is compatible with java 7, it
must parse Java's version sysprop.

This commit reworks the checker to no longer need to parse the version.
Instead, it uses a multi-release-jar, so that there are two versions of
the main class. The Java 7 compatible version simply exits with an error
message. The Java 17 version simple exits with no error.

relates #85758
Ryan Ernst 3 years ago
parent
commit
b361ff2335

+ 21 - 6
distribution/tools/java-version-checker/build.gradle

@@ -1,12 +1,27 @@
-apply plugin: 'elasticsearch.build'
+apply plugin: 'elasticsearch.java'
 
-targetCompatibility = JavaVersion.VERSION_1_7
+sourceSets {
+  unsupportedJdkVersionEntrypoint
+}
+
+tasks.named(sourceSets.unsupportedJdkVersionEntrypoint.compileJavaTaskName).configure {
+  targetCompatibility = JavaVersion.VERSION_1_7
+}
+
+tasks.named("jar") {
+  manifest {
+    attributes("Multi-Release": "true")
+  }
 
-// java_version_checker do not depend on core so only JDK signatures should be checked
-tasks.named('forbiddenApisMain').configure {
-  replaceSignatureFiles 'jdk-signatures'
+  from(sourceSets.unsupportedJdkVersionEntrypoint.output)
+  eachFile { details ->
+    if (details.path.equals("org/elasticsearch/tools/java_version_checker/JavaVersionChecker.class") &&
+      sourceSets.main.output.asFileTree.contains(details.file)) {
+      details.relativePath = details.relativePath.prepend("META-INF/versions/17")
+    }
+  }
 }
 
-["test", "javadoc", "loggerUsageCheck", "jarHell"].each {
+["test", "javadoc"].each {
   tasks.named(it).configure { enabled = false }
 }

+ 0 - 60
distribution/tools/java-version-checker/src/main/java/org/elasticsearch/tools/java_version_checker/JavaVersion.java

@@ -1,60 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-package org.elasticsearch.tools.java_version_checker;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-public class JavaVersion {
-
-    public static final List<Integer> CURRENT = parse(System.getProperty("java.specification.version"));
-    public static final List<Integer> JAVA_17 = parse("17");
-
-    private JavaVersion() {}
-
-    static List<Integer> parse(final String value) {
-        if (value.matches("^0*[0-9]+(\\.[0-9]+)*$") == false) {
-            throw new IllegalArgumentException(value);
-        }
-
-        final List<Integer> version = new ArrayList<Integer>();
-        final String[] components = value.split("\\.");
-        for (final String component : components) {
-            version.add(Integer.valueOf(component));
-        }
-        return version;
-    }
-
-    public static int majorVersion(final List<Integer> javaVersion) {
-        Objects.requireNonNull(javaVersion);
-        if (javaVersion.get(0) > 1) {
-            return javaVersion.get(0);
-        } else {
-            return javaVersion.get(1);
-        }
-    }
-
-    static int compare(final List<Integer> left, final List<Integer> right) {
-        // lexicographically compare two lists, treating missing entries as zeros
-        final int len = Math.max(left.size(), right.size());
-        for (int i = 0; i < len; i++) {
-            final int l = (i < left.size()) ? left.get(i) : 0;
-            final int r = (i < right.size()) ? right.get(i) : 0;
-            if (l < r) {
-                return -1;
-            }
-            if (r < l) {
-                return 1;
-            }
-        }
-        return 0;
-    }
-
-}

+ 1 - 38
distribution/tools/java-version-checker/src/main/java/org/elasticsearch/tools/java_version_checker/JavaVersionChecker.java

@@ -9,55 +9,18 @@
 package org.elasticsearch.tools.java_version_checker;
 
 import java.util.Arrays;
-import java.util.Locale;
 
 /**
- * Simple program that checks if the runtime Java version is at least 17.
+ * Java 17 compatible main which just exits without error.
  */
 final class JavaVersionChecker {
 
     private JavaVersionChecker() {}
 
-    /**
-     * The main entry point. The exit code is 0 if the Java version is at least 17, otherwise the exit code is 1.
-     *
-     * @param args the args to the program which are rejected if not empty
-     */
     public static void main(final String[] args) {
         // no leniency!
         if (args.length != 0) {
             throw new IllegalArgumentException("expected zero arguments but was " + Arrays.toString(args));
         }
-        if (JavaVersion.compare(JavaVersion.CURRENT, JavaVersion.JAVA_17) < 0) {
-            final String message = String.format(
-                Locale.ROOT,
-                "The minimum required Java version is 17; your Java version from [%s] does not meet this requirement",
-                System.getProperty("java.home")
-            );
-            errPrintln(message);
-            exit(1);
-        }
-        exit(0);
-    }
-
-    /**
-     * Prints a string and terminates the line on standard error.
-     *
-     * @param message the message to print
-     */
-    @SuppressForbidden(reason = "System#err")
-    static void errPrintln(final String message) {
-        System.err.println(message);
     }
-
-    /**
-     * Exit the VM with the specified status.
-     *
-     * @param status the status
-     */
-    @SuppressForbidden(reason = "System#exit")
-    static void exit(final int status) {
-        System.exit(status);
-    }
-
 }

+ 35 - 0
distribution/tools/java-version-checker/src/unsupportedJdkVersionEntrypoint/java/org/elasticsearch/tools/java_version_checker/JavaVersionChecker.java

@@ -0,0 +1,35 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+package org.elasticsearch.tools.java_version_checker;
+
+import java.util.Arrays;
+import java.util.Locale;
+
+/**
+ * Java 7 compatible main which exits with an error.
+ */
+final class JavaVersionChecker {
+
+    private JavaVersionChecker() {}
+
+    public static void main(final String[] args) {
+        // no leniency!
+        if (args.length != 0) {
+            throw new IllegalArgumentException("expected zero arguments but was " + Arrays.toString(args));
+        }
+        final String message = String.format(
+            Locale.ROOT,
+            "The minimum required Java version is 17; your Java version %s from [%s] does not meet that requirement.",
+            System.getProperty("java.specification.version"),
+            System.getProperty("java.home")
+        );
+        System.err.println(message);
+        System.exit(1);
+    }
+}

+ 1 - 4
distribution/tools/launchers/src/main/java/org/elasticsearch/tools/launchers/DefaultSystemMemoryInfo.java

@@ -10,9 +10,6 @@ package org.elasticsearch.tools.launchers;
 
 import com.sun.management.OperatingSystemMXBean;
 
-import org.elasticsearch.tools.java_version_checker.JavaVersion;
-import org.elasticsearch.tools.java_version_checker.SuppressForbidden;
-
 import java.lang.management.ManagementFactory;
 
 /**
@@ -32,7 +29,7 @@ public final class DefaultSystemMemoryInfo implements SystemMemoryInfo {
     @Override
     @SuppressWarnings("deprecation")
     public long availableSystemMemory() throws SystemMemoryInfoException {
-        if (JavaVersion.majorVersion(JavaVersion.CURRENT) < 14) {
+        if (Runtime.version().feature() < 14) {
             throw new SystemMemoryInfoException("The minimum required Java version is 14 to use " + this.getClass().getName());
         }
 

+ 1 - 3
distribution/tools/launchers/src/main/java/org/elasticsearch/tools/launchers/JvmOptionsParser.java

@@ -8,8 +8,6 @@
 
 package org.elasticsearch.tools.launchers;
 
-import org.elasticsearch.tools.java_version_checker.JavaVersion;
-
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
@@ -170,7 +168,7 @@ final class JvmOptionsParser {
                 Reader reader = new InputStreamReader(is, StandardCharsets.UTF_8);
                 BufferedReader br = new BufferedReader(reader)
             ) {
-                parse(JavaVersion.majorVersion(JavaVersion.CURRENT), br, jvmOptions::add, invalidLines::put);
+                parse(Runtime.version().feature(), br, jvmOptions::add, invalidLines::put);
             }
             if (invalidLines.isEmpty() == false) {
                 throw new JvmOptionsFileParserException(jvmOptionsFile, invalidLines);

+ 0 - 2
distribution/tools/launchers/src/main/java/org/elasticsearch/tools/launchers/Launchers.java

@@ -8,8 +8,6 @@
 
 package org.elasticsearch.tools.launchers;
 
-import org.elasticsearch.tools.java_version_checker.SuppressForbidden;
-
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;

+ 1 - 1
distribution/tools/java-version-checker/src/main/java/org/elasticsearch/tools/java_version_checker/SuppressForbidden.java → distribution/tools/launchers/src/main/java/org/elasticsearch/tools/launchers/SuppressForbidden.java

@@ -6,7 +6,7 @@
  * Side Public License, v 1.
  */
 
-package org.elasticsearch.tools.java_version_checker;
+package org.elasticsearch.tools.launchers;
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;