diff --git a/logstash-core/src/main/java/org/logstash/JavaVersionUtils.java b/logstash-core/src/main/java/org/logstash/JavaVersionUtils.java new file mode 100644 index 00000000000..b83f54b5ee0 --- /dev/null +++ b/logstash-core/src/main/java/org/logstash/JavaVersionUtils.java @@ -0,0 +1,45 @@ +/* + * 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; + +/** + * Helper Class for dealing with Java versions + */ +public final class JavaVersionUtils { + + /** + * Identifies whether we are running on a version greater than or equal to the version parameter specified. + * @param version The version to test against. This must be the Major version of Java + * @return True if running on Java whose major version is greater than or equal to the + * specified version. + */ + public static boolean isJavaAtLeast(int version) { + final String value = System.getProperty("java.specification.version"); + final int actualVersion; + // Java specification version prior to Java 9 were of the format `1.X`, and after the format `X` + // See https://openjdk.java.net/jeps/223 + if (value.startsWith("1.")) { + actualVersion = Integer.parseInt(value.split("\\.")[1]); + } else { + actualVersion = Integer.parseInt(value); + } + return actualVersion >= version; + } +} \ No newline at end of file diff --git a/logstash-core/src/main/java/org/logstash/LogstashJavaCompat.java b/logstash-core/src/main/java/org/logstash/LogstashJavaCompat.java deleted file mode 100644 index 75e9da83061..00000000000 --- a/logstash-core/src/main/java/org/logstash/LogstashJavaCompat.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 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; - -import java.io.StringReader; -import java.util.ArrayList; -import java.util.Collection; -import org.codehaus.janino.ClassBodyEvaluator; -import org.logstash.ackedqueue.io.ByteBufferCleaner; - -/** - * Logic around ensuring compatibility with Java 8 and 9 simultaneously. - */ -public final class LogstashJavaCompat { - - /** - * True if current JVM is a Java 9 implementation. - */ - public static final boolean IS_JAVA_9_OR_GREATER = isAtLeastJava9(); - - /** - * Sets up an appropriate implementation of {@link ByteBufferCleaner} depending no whether or - * not the current JVM is a Java 9 implementation. - * @return ByteBufferCleaner - */ - @SuppressWarnings("rawtypes") - public static ByteBufferCleaner setupBytebufferCleaner() { - final ClassBodyEvaluator se = new ClassBodyEvaluator(); - final Collection imports = new ArrayList<>(); - imports.add("java.nio.MappedByteBuffer"); - final String cleanerCode; - final String ctorCode; - final String fieldsCode; - if (isAtLeastJava9()) { - imports.add("sun.misc.Unsafe"); - imports.add("java.lang.reflect.Field"); - cleanerCode = "unsafe.invokeCleaner(buffer);"; - ctorCode = "Field unsafeField = Unsafe.class.getDeclaredField(\"theUnsafe\");" + - "unsafeField.setAccessible(true);" + - "unsafe = (Unsafe) unsafeField.get(null);"; - fieldsCode = "private final Unsafe unsafe;"; - } else { - imports.add("sun.misc.Cleaner"); - imports.add("sun.nio.ch.DirectBuffer"); - cleanerCode = "Cleaner c=((DirectBuffer)buffer).cleaner();if(c != null){c.clean();}"; - ctorCode = ""; - fieldsCode = ""; - } - se.setImplementedInterfaces(new Class[]{ByteBufferCleaner.class}); - se.setClassName("ByteBufferCleanerImpl"); - se.setDefaultImports(imports.toArray(new String[0])); - try { - return (ByteBufferCleaner) se.createInstance( - new StringReader(String.format( - "%s public ByteBufferCleanerImpl() throws Exception{%s} public void clean(MappedByteBuffer buffer){%s}", - fieldsCode, ctorCode, cleanerCode - )) - ); - } catch (final Exception ex) { - throw new IllegalStateException(ex); - } - } - - /** - * Identifies whether we're running on Java 9 by parsing the first component of the - * {@code "java.version"} system property. For Java 9 this value is assumed to start with a - * {@code "9"}. - * @return True iff running on Java 9 - */ - private static boolean isAtLeastJava9() { - final String version = System.getProperty("java.version"); - final int end = version.indexOf('.'); - return Integer.parseInt(version.substring(0, end > 0 ? end : version.length())) >= 9; - } - - /** - * Identifies whether we are running on a versiongreater than or equal to the version parameter specified. - * @param version The version to test against. This must be the Major version of Java - * @return True if running on Java whose major version is greater than or equal to the - * specified version. - */ - public static boolean isJavaAtLeast(int version) { - final String value = System.getProperty("java.specification.version"); - final int actualVersion; - // Java specification version prior to Java 9 were of the format `1.X`, and after the format `X` - // See https://openjdk.java.net/jeps/223 - if (value.startsWith("1.")) { - actualVersion = Integer.parseInt(value.split("\\.")[1]); - } else { - actualVersion = Integer.parseInt(value); - } - return actualVersion >= version; - } -} diff --git a/logstash-core/src/main/java/org/logstash/ackedqueue/io/ByteBufferCleanerImpl.java b/logstash-core/src/main/java/org/logstash/ackedqueue/io/ByteBufferCleanerImpl.java new file mode 100644 index 00000000000..b9ce84c8fc9 --- /dev/null +++ b/logstash-core/src/main/java/org/logstash/ackedqueue/io/ByteBufferCleanerImpl.java @@ -0,0 +1,26 @@ +package org.logstash.ackedqueue.io; + +import java.nio.MappedByteBuffer; + +import sun.misc.Unsafe; +import java.lang.reflect.Field; + +public class ByteBufferCleanerImpl implements ByteBufferCleaner { + + private final Unsafe unsafe; + + public ByteBufferCleanerImpl() { + try { + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + unsafe = (Unsafe) unsafeField.get(null); + }catch (Exception e){ + throw new IllegalStateException(e); + } + } + + @Override + public void clean(MappedByteBuffer buffer) { + unsafe.invokeCleaner(buffer); + } +} diff --git a/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV1.java b/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV1.java index 3c306ac0306..0bf3a009ad6 100644 --- a/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV1.java +++ b/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV1.java @@ -29,7 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.zip.CRC32; -import org.logstash.LogstashJavaCompat; + import org.logstash.ackedqueue.SequencedList; /** @@ -43,8 +43,7 @@ public final class MmapPageIOV1 implements PageIO { /** * Cleaner function for forcing unmapping of backing {@link MmapPageIOV1#buffer}. */ - private static final ByteBufferCleaner BUFFER_CLEANER = - LogstashJavaCompat.setupBytebufferCleaner(); + private static final ByteBufferCleaner BUFFER_CLEANER = new ByteBufferCleanerImpl(); private final File file; diff --git a/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV2.java b/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV2.java index 0de29a41c88..c68368f9076 100644 --- a/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV2.java +++ b/logstash-core/src/main/java/org/logstash/ackedqueue/io/MmapPageIOV2.java @@ -32,7 +32,6 @@ import java.util.zip.CRC32; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.logstash.LogstashJavaCompat; import org.logstash.ackedqueue.SequencedList; /** @@ -54,8 +53,7 @@ public final class MmapPageIOV2 implements PageIO { /** * Cleaner function for forcing unmapping of backing {@link MmapPageIOV2#buffer}. */ - private static final ByteBufferCleaner BUFFER_CLEANER = - LogstashJavaCompat.setupBytebufferCleaner(); + private static final ByteBufferCleaner BUFFER_CLEANER = new ByteBufferCleanerImpl(); private final File file; diff --git a/logstash-core/src/main/java/org/logstash/instrument/monitors/ProcessMonitor.java b/logstash-core/src/main/java/org/logstash/instrument/monitors/ProcessMonitor.java index 287fa061e44..32f6236879d 100644 --- a/logstash-core/src/main/java/org/logstash/instrument/monitors/ProcessMonitor.java +++ b/logstash-core/src/main/java/org/logstash/instrument/monitors/ProcessMonitor.java @@ -30,8 +30,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.logstash.Logstash; -import org.logstash.LogstashJavaCompat; +import org.logstash.JavaVersionUtils; public class ProcessMonitor { @@ -119,7 +118,7 @@ private short getSystemCpuLoad() { */ private static Method getCpuLoadMethod(){ try{ - String methodName = (LogstashJavaCompat.isJavaAtLeast(14)) ? "getCpuLoad" : "getSystemCpuLoad"; + String methodName = (JavaVersionUtils.isJavaAtLeast(14)) ? "getCpuLoad" : "getSystemCpuLoad"; return Class.forName("com.sun.management.OperatingSystemMXBean").getMethod(methodName); } catch (ReflectiveOperationException e){ LOGGER.warn("OperatingSystemMXBean CPU load method not available, CPU load will not be measured", e); diff --git a/logstash-core/src/test/java/org/logstash/instruments/monitors/MemoryMonitorTest.java b/logstash-core/src/test/java/org/logstash/instruments/monitors/MemoryMonitorTest.java index 67891879e4e..3e1be5831f5 100644 --- a/logstash-core/src/test/java/org/logstash/instruments/monitors/MemoryMonitorTest.java +++ b/logstash-core/src/test/java/org/logstash/instruments/monitors/MemoryMonitorTest.java @@ -21,7 +21,6 @@ package org.logstash.instruments.monitors; import org.junit.Test; -import org.logstash.LogstashJavaCompat; import org.logstash.instrument.monitors.MemoryMonitor; import java.util.Map; @@ -38,11 +37,7 @@ public class MemoryMonitorTest { public void testEachHeapSpaceRepresented() { Map> heap = MemoryMonitor.detect(MemoryMonitor.Type.All).getHeap(); assertThat(heap, notNullValue()); - if (LogstashJavaCompat.IS_JAVA_9_OR_GREATER) { - assertThat(heap.keySet(), hasItems("G1 Old Gen", "G1 Survivor Space", "G1 Eden Space")); - } else { - assertThat(heap.keySet(), hasItems("PS Survivor Space", "PS Old Gen", "PS Eden Space")); - } + assertThat(heap.keySet(), hasItems("G1 Old Gen", "G1 Survivor Space", "G1 Eden Space")); } @Test diff --git a/logstash-core/src/test/java/org/logstash/secret/store/backend/JavaKeyStoreTest.java b/logstash-core/src/test/java/org/logstash/secret/store/backend/JavaKeyStoreTest.java index 39834ae7916..02b49ba4a51 100644 --- a/logstash-core/src/test/java/org/logstash/secret/store/backend/JavaKeyStoreTest.java +++ b/logstash-core/src/test/java/org/logstash/secret/store/backend/JavaKeyStoreTest.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.logstash.LogstashJavaCompat; import org.logstash.secret.SecretIdentifier; import org.logstash.secret.store.SecretStore; import org.logstash.secret.store.SecretStoreException; @@ -48,7 +47,6 @@ import java.nio.file.attribute.PosixFilePermission; import java.util.*; import java.util.concurrent.Callable; -import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;