Browse Source

Add early-access check

The OpenJDK project provides early-access builds of upcoming
releases. These early-access builds are not suitable for
production. These builds sometimes end up on systems due to aggressive
packaging (e.g., Ubuntu). This commit adds a bootstrap check to ensure
these early-access builds are not being used in production.

Relates #23743
Jason Tedor 8 years ago
parent
commit
a6c4234575

+ 29 - 0
core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java

@@ -195,6 +195,7 @@ final class BootstrapChecks {
         checks.add(new SystemCallFilterCheck(BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(settings)));
         checks.add(new OnErrorCheck());
         checks.add(new OnOutOfMemoryErrorCheck());
+        checks.add(new EarlyAccessCheck());
         checks.add(new G1GCCheck());
         return Collections.unmodifiableList(checks);
     }
@@ -577,6 +578,34 @@ final class BootstrapChecks {
 
     }
 
+    /**
+     * Bootstrap check for early-access builds from OpenJDK.
+     */
+    static class EarlyAccessCheck implements BootstrapCheck {
+
+        @Override
+        public boolean check() {
+            return "Oracle Corporation".equals(jvmVendor()) && javaVersion().endsWith("-ea");
+        }
+
+        String jvmVendor() {
+            return Constants.JVM_VENDOR;
+        }
+
+        String javaVersion() {
+            return Constants.JAVA_VERSION;
+        }
+
+        @Override
+        public String errorMessage() {
+            return String.format(
+                    Locale.ROOT,
+                    "Java version [%s] is an early-access build, only use release builds",
+                    javaVersion());
+        }
+
+    }
+
     /**
      * Bootstrap check for versions of HotSpot that are known to have issues that can lead to index corruption when G1GC is enabled.
      */

+ 40 - 4
core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java

@@ -560,12 +560,48 @@ public class BootstrapChecksTests extends ESTestCase {
         consumer.accept(e);
     }
 
+    public void testEarlyAccessCheck() throws NodeValidationException {
+        final AtomicReference<String> javaVersion
+                = new AtomicReference<>(randomFrom("1.8.0_152-ea", "9-ea"));
+        final BootstrapChecks.EarlyAccessCheck eaCheck = new BootstrapChecks.EarlyAccessCheck() {
+
+            @Override
+            String jvmVendor() {
+                return "Oracle Corporation";
+            }
+
+            @Override
+            String javaVersion() {
+                return javaVersion.get();
+            }
+
+        };
+
+        final List<BootstrapCheck> checks = Collections.singletonList(eaCheck);
+        final NodeValidationException e = expectThrows(
+                NodeValidationException.class,
+                () -> {
+                    BootstrapChecks.check(true, checks, "testEarlyAccessCheck");
+                });
+        assertThat(
+                e.getMessage(),
+                containsString(
+                        "Java version ["
+                                + javaVersion.get()
+                                + "] is an early-access build, only use release builds"));
+
+        // if not on an early-access build, nothing should happen
+        javaVersion.set(randomFrom("1.8.0_152", "9"));
+        BootstrapChecks.check(true, checks, "testEarlyAccessCheck");
+
+    }
+
     public void testG1GCCheck() throws NodeValidationException {
         final AtomicBoolean isG1GCEnabled = new AtomicBoolean(true);
         final AtomicBoolean isJava8 = new AtomicBoolean(true);
         final AtomicReference<String> jvmVersion =
             new AtomicReference<>(String.format(Locale.ROOT, "25.%d-b%d", randomIntBetween(0, 39), randomIntBetween(1, 128)));
-        final BootstrapChecks.G1GCCheck oracleCheck = new BootstrapChecks.G1GCCheck() {
+        final BootstrapChecks.G1GCCheck g1GCCheck = new BootstrapChecks.G1GCCheck() {
 
             @Override
             String jvmVendor() {
@@ -592,7 +628,7 @@ public class BootstrapChecksTests extends ESTestCase {
         final NodeValidationException e =
             expectThrows(
                 NodeValidationException.class,
-                () -> BootstrapChecks.check(true, Collections.singletonList(oracleCheck), "testG1GCCheck"));
+                () -> BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck"));
         assertThat(
             e.getMessage(),
             containsString(
@@ -600,12 +636,12 @@ public class BootstrapChecksTests extends ESTestCase {
 
         // if G1GC is disabled, nothing should happen
         isG1GCEnabled.set(false);
-        BootstrapChecks.check(true, Collections.singletonList(oracleCheck), "testG1GCCheck");
+        BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck");
 
         // if on or after update 40, nothing should happen independent of whether or not G1GC is enabled
         isG1GCEnabled.set(randomBoolean());
         jvmVersion.set(String.format(Locale.ROOT, "25.%d-b%d", randomIntBetween(40, 112), randomIntBetween(1, 128)));
-        BootstrapChecks.check(true, Collections.singletonList(oracleCheck), "testG1GCCheck");
+        BootstrapChecks.check(true, Collections.singletonList(g1GCCheck), "testG1GCCheck");
 
         final BootstrapChecks.G1GCCheck nonOracleCheck = new BootstrapChecks.G1GCCheck() {
 

+ 7 - 0
docs/reference/setup/bootstrap-checks.asciidoc

@@ -179,6 +179,13 @@ use the JVM flag `ExitOnOutOfMemoryError`. While this does not have the
 full capabilities of `OnError` nor `OnOutOfMemoryError`, arbitrary
 forking will not be supported with seccomp enabled.
 
+=== Early-access check
+
+The OpenJDK project provides early-access snapshots of upcoming releases. These
+releases are not suitable for production. The early-access check detects these
+early-access snapshots. To pass this check, you must start Elasticsearch on a
+release build of the JVM.
+
 === G1GC check
 
 Early versions of the HotSpot JVM that shipped with JDK 8 are known to have