Introduce Java version checker
Today when users start Elasticsearch with their Java configuration pointing to a pre-Java 8 install, they encounter a cryptic message: Exception in thread "main" java.lang.UnsupportedClassVersionError: org/elasticsearch/bootstrap/Elasticsearch : Unsupported major.minor version 52.0 They often think that they have Java 8 installed but if their JAVA_HOME or other configuration is causing them to start with a pre-Java 8 install, this error message does not help them. We introduce a Java version checker that runs on Java 6 as part of the startup scripts. If the Java version is pre-Java 8, we can display a helpful error message to the user informing them of the Java version that the runtime was started with. Otherwise, Elasticsearch starts as it does today.
This commit is contained in:
parent
60b823c756
commit
c9cde11a5e
|
@ -143,6 +143,13 @@ if [ "x$JAVA_OPTS" != "x" ]; then
|
|||
echo "Please pass JVM parameters via ES_JAVA_OPTS instead"
|
||||
fi
|
||||
|
||||
"$JAVA" -cp "$ES_CLASSPATH" org.elasticsearch.tools.JavaVersionChecker
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Elasticsearch requires at least Java 8 but your Java version from $JAVA does not meet this requirement"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# full hostname passed through cut for portability on systems that do not support hostname -s
|
||||
# export on separate line for shells that do not support combining definition and export
|
||||
HOSTNAME=`hostname | cut -d. -f1`
|
||||
|
|
|
@ -22,4 +22,12 @@ ECHO additional elements via the plugin mechanism, or if code must really be 1>&
|
|||
ECHO added to the main classpath, add jars to lib\, unsupported 1>&2
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
%JAVA% -cp "%ES_CLASSPATH%" "org.elasticsearch.tools.JavaVersionChecker"
|
||||
|
||||
IF ERRORLEVEL 1 (
|
||||
ECHO Elasticsearch requires at least Java 8 but your Java version from %JAVA% does not meet this requirement
|
||||
EXIT /B 1
|
||||
)
|
||||
|
||||
set ES_PARAMS=-Delasticsearch -Des.path.home="%ES_HOME%"
|
||||
|
|
|
@ -17,12 +17,25 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
|
||||
import org.elasticsearch.gradle.precommit.PrecommitTasks
|
||||
import org.gradle.api.JavaVersion
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'ru.vyarus.animalsniffer'
|
||||
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
sourceCompatibility = JavaVersion.VERSION_1_6
|
||||
targetCompatibility = JavaVersion.VERSION_1_6
|
||||
|
||||
dependencies {
|
||||
signature "org.codehaus.mojo.signature:java16:1.0@signature"
|
||||
}
|
||||
|
||||
forbiddenApisMain {
|
||||
// java-version-checker does not depend on core so only JDK signatures should be checked
|
||||
signaturesURLs = [PrecommitTasks.getResource('/forbidden/jdk-signatures.txt')]
|
||||
}
|
||||
|
||||
test.enabled = false
|
||||
loggerUsageCheck.enabled = false
|
||||
jarHell.enabled=false
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Simple program that checks if the runtime Java version is at least 1.8.
|
||||
*/
|
||||
final class JavaVersionChecker {
|
||||
|
||||
private JavaVersionChecker() {
|
||||
}
|
||||
|
||||
private static final List<Integer> JAVA_8 = Arrays.asList(1, 8);
|
||||
|
||||
/**
|
||||
* The main entry point. The exit code is 0 if the Java version is at least 1.8, 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));
|
||||
}
|
||||
final String javaSpecificationVersion = System.getProperty("java.specification.version");
|
||||
final List<Integer> current = parse(javaSpecificationVersion);
|
||||
if (compare(current, JAVA_8) < 0) {
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
private static List<Integer> parse(final String value) {
|
||||
if (!value.matches("^0*[0-9]+(\\.[0-9]+)*$")) {
|
||||
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;
|
||||
}
|
||||
|
||||
private 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;
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "exit")
|
||||
private static void exit(final int status) {
|
||||
System.exit(status);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.tools;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
/**
|
||||
* Annotation to suppress forbidden-apis errors inside a whole class, a method, or a field.
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
|
||||
@interface SuppressForbidden {
|
||||
String reason();
|
||||
}
|
Loading…
Reference in New Issue