From ac796f5d1e620b255795462eb52d9c85ca5c0c60 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 24 Mar 2017 14:33:34 -0400 Subject: [PATCH 1/3] 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. --- .../bootstrap/BootstrapChecks.java | 31 +++++++++++++ .../bootstrap/BootstrapChecksTests.java | 44 +++++++++++++++++-- .../reference/setup/bootstrap-checks.asciidoc | 7 +++ 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 7e82852a9f3cc..bfc491f589b54 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -195,6 +195,7 @@ static List checks(final Settings settings) { 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,36 @@ public String errorMessage() { } + static class EarlyAccessCheck implements BootstrapCheck { + + @Override + public boolean check() { + if ("Oracle Corporation".equals(jvmVendor())) { + final String javaVersion = javaVersion(); + return javaVersion.endsWith("-ea"); + } else { + return false; + } + } + + 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. */ diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java index bd553cff6e190..c3e08b81d6c3e 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapChecksTests.java @@ -560,12 +560,48 @@ private void runMightForkTest( consumer.accept(e); } + public void testEarlyAccessCheck() throws NodeValidationException { + final AtomicReference 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 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 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 @@ boolean isJava8() { 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 @@ boolean isJava8() { // 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() { diff --git a/docs/reference/setup/bootstrap-checks.asciidoc b/docs/reference/setup/bootstrap-checks.asciidoc index 22c3f03cd3633..2d18911beb67e 100644 --- a/docs/reference/setup/bootstrap-checks.asciidoc +++ b/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 From d97171c79b456965fd57cefe33ee354aede6f238 Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 24 Mar 2017 14:37:58 -0400 Subject: [PATCH 2/3] Add Javadoc for early-access check --- .../main/java/org/elasticsearch/bootstrap/BootstrapChecks.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index bfc491f589b54..8121f268635b9 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -578,6 +578,9 @@ public String errorMessage() { } + /** + * Bootstrap check for early-access builds from OpenJDK. + */ static class EarlyAccessCheck implements BootstrapCheck { @Override From 6cf944e4c69b5b5dc7f2e7400e67a1bc62a62ced Mon Sep 17 00:00:00 2001 From: Jason Tedor Date: Fri, 24 Mar 2017 14:49:02 -0400 Subject: [PATCH 3/3] Brevity --- .../java/org/elasticsearch/bootstrap/BootstrapChecks.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 8121f268635b9..a9758267ff3f1 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -585,12 +585,7 @@ static class EarlyAccessCheck implements BootstrapCheck { @Override public boolean check() { - if ("Oracle Corporation".equals(jvmVendor())) { - final String javaVersion = javaVersion(); - return javaVersion.endsWith("-ea"); - } else { - return false; - } + return "Oracle Corporation".equals(jvmVendor()) && javaVersion().endsWith("-ea"); } String jvmVendor() {