From 9061625b89c29567d41f6b5bfd5af1e02cf99d36 Mon Sep 17 00:00:00 2001 From: Rob Bavey Date: Tue, 4 Jan 2022 09:57:39 -0500 Subject: [PATCH] Backport PR#13533 to 8.0: Add JavaVersionChecker to check Java version for compatibility before running Backport PR#13433 to 8.0 branch. Original message: Provides a "friendly" error message when running Logstash with an incompatible version of Java Readded from #13356, incorporated with use of Comparable from #13358 --- bin/logstash.bat | 3 + bin/logstash.lib.sh | 5 ++ .../org/logstash/util/JavaVersionChecker.java | 73 +++++++++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 logstash-core/src/main/java/org/logstash/util/JavaVersionChecker.java diff --git a/bin/logstash.bat b/bin/logstash.bat index 28850bb8f73..08f32925f7e 100644 --- a/bin/logstash.bat +++ b/bin/logstash.bat @@ -47,6 +47,9 @@ if "%MAYBE_JVM_OPTIONS_PARSER_FAILED%" == "jvm_options_parser_failed" ( ) set JAVA_OPTS=%LS_JAVA_OPTS% +rem check the Java version +%JAVA% -cp "%CLASSPATH%" "org.logstash.util.JavaVersionChecker" || exit /b 1 + %JAVA% %JAVA_OPTS% -cp "%CLASSPATH%" org.logstash.Logstash %* goto :end diff --git a/bin/logstash.lib.sh b/bin/logstash.lib.sh index efd7f49a401..28096f70824 100755 --- a/bin/logstash.lib.sh +++ b/bin/logstash.lib.sh @@ -138,6 +138,11 @@ setup_java() { export JAVACMD CLASSPATH="$(setup_classpath $LOGSTASH_JARS)" + + # Verify the version of Java being used, and exit if the wrong version of Java is not available. + if ! "${JAVACMD}" -cp "${CLASSPATH}" org.logstash.util.JavaVersionChecker ; then + exit 1 + fi JAVA_OPTS=`exec "${JAVACMD}" -cp "${CLASSPATH}" org.logstash.launchers.JvmOptionsParser "$LOGSTASH_HOME" "$LS_JVM_OPTS"` unset CLASSPATH export JAVA_OPTS diff --git a/logstash-core/src/main/java/org/logstash/util/JavaVersionChecker.java b/logstash-core/src/main/java/org/logstash/util/JavaVersionChecker.java new file mode 100644 index 00000000000..c46eeadb083 --- /dev/null +++ b/logstash-core/src/main/java/org/logstash/util/JavaVersionChecker.java @@ -0,0 +1,73 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.logstash.util; + +import java.util.Arrays; +import java.util.Locale; + +/** + * Simple program that checks if the runtime Java version is at least 11. + * Based on JavaVersionChecker from Elasticsearch + */ +final class JavaVersionChecker { + + private JavaVersionChecker() {} + + /** + * The main entry point. The exit code is 0 if the Java version is at least 11, 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.CURRENT.compareTo(JavaVersion.JAVA_11) < 0) { + final String message = String.format( + Locale.ROOT, + "the minimum required Java version is 11; 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 + */ + static void errPrintln(final String message) { + System.err.println(message); + } + + /** + * Exit the VM with the specified status. + * + * @param status the status + */ + static void exit(final int status) { + System.exit(status); + } + +} \ No newline at end of file