diff --git a/agent/src/main/java/reactor/blockhound/BlockHound.java b/agent/src/main/java/reactor/blockhound/BlockHound.java index 60be4eb..60d0d55 100644 --- a/agent/src/main/java/reactor/blockhound/BlockHound.java +++ b/agent/src/main/java/reactor/blockhound/BlockHound.java @@ -134,8 +134,6 @@ public TypePool typePool(ClassFileLocator classFileLocator, ClassLoader classLoa public static class Builder { private final Map>> blockingMethods = new HashMap>>() {{ - int jdkMajorVersion = InstrumentationUtils.getJdkMajorVersion(); - put("java/lang/Object", new HashMap>() {{ put("wait", singleton("(J)V")); }}); @@ -196,7 +194,7 @@ public static class Builder { put("writeBytes", singleton("([BIIZ)V")); }}); - if (jdkMajorVersion >= 9) { + if (InstrumentationUtils.jdkMajorVersion >= 9) { put("jdk/internal/misc/Unsafe", new HashMap>() {{ put("park", singleton("(ZJ)V")); }}); @@ -213,7 +211,7 @@ public static class Builder { }}); } - if (jdkMajorVersion < 19) { + if (InstrumentationUtils.jdkMajorVersion < 19) { // for jdk version < 19, the native method for Thread.sleep is "sleep" put("java/lang/Thread", new HashMap>() {{ put("sleep", singleton("(J)V")); @@ -221,7 +219,7 @@ public static class Builder { put("onSpinWait", singleton("()V")); }}); } - else if (jdkMajorVersion >= 19 && jdkMajorVersion <= 21) { + else if (InstrumentationUtils.jdkMajorVersion >= 19 && InstrumentationUtils.jdkMajorVersion <= 21) { // for jdk version in the range [19, 21], the native method for Thread.sleep is "sleep0" put("java/lang/Thread", new HashMap>() {{ put("sleep0", singleton("(J)V")); diff --git a/agent/src/main/java/reactor/blockhound/InstrumentationUtils.java b/agent/src/main/java/reactor/blockhound/InstrumentationUtils.java index c88c2b4..0504d84 100644 --- a/agent/src/main/java/reactor/blockhound/InstrumentationUtils.java +++ b/agent/src/main/java/reactor/blockhound/InstrumentationUtils.java @@ -34,6 +34,20 @@ class InstrumentationUtils { + /** + * Constant used to indicate the current JDK major version (8,9,..22,...) + */ + static final int jdkMajorVersion; + + static { + try { + jdkMajorVersion = getJdkMajorVersion(); + } + catch (InvocationTargetException | IllegalAccessException e) { + throw new ExceptionInInitializerError(e); + } + } + static void injectBootstrapClasses(Instrumentation instrumentation, String... classNames) throws IOException { File tempJarFile = File.createTempFile("BlockHound", ".jar"); tempJarFile.deleteOnExit(); @@ -83,7 +97,7 @@ public void visit(int version, int access, String name, String signature, String * * @return the current jdk major version (8, 9, 10, ... 22) */ - static int getJdkMajorVersion() { + private static int getJdkMajorVersion() throws InvocationTargetException, IllegalAccessException { Object version = getRuntimeVersion(); if (version == null) { @@ -98,7 +112,7 @@ static int getJdkMajorVersion() { * * @return the detected JDK version object or null if not available */ - private static Object getRuntimeVersion() { + private static Object getRuntimeVersion() throws InvocationTargetException, IllegalAccessException { Runtime runtime = Runtime.getRuntime(); try { Method versionMethod = runtime.getClass().getMethod("version"); @@ -109,11 +123,6 @@ private static Object getRuntimeVersion() { // Method Runtime.version() not found -> return null, meaning JDK 8 return null; // JDK 8 } - - catch (IllegalAccessException | InvocationTargetException e) { - // if the Runtime.version() method exists, we should be able to invoke it, consider this is an error state - throw new IllegalStateException("Could not invoke Runtime.version() method", e); - } } /** @@ -122,7 +131,7 @@ private static Object getRuntimeVersion() { * @param version the JDK version object * @return the major version (9, 10, ...) */ - private static int getRuntimeVersionFeature(Object version) { + private static int getRuntimeVersionFeature(Object version) throws InvocationTargetException, IllegalAccessException { try { Method featureMethod = version.getClass().getMethod("feature"); Object feature = featureMethod.invoke(version); @@ -133,11 +142,6 @@ private static int getRuntimeVersionFeature(Object version) { // Version.feature() method not found -> JDK 9 (because feature method is only available starting from JDK10 +) return 9; } - - catch (IllegalAccessException | InvocationTargetException e) { - // if the Runtime.version().feature() method exists, we should be able to invoke it, consider this is an error state - throw new IllegalStateException("Could not invoke Runtime.version().feature() method", e); - } } } diff --git a/agent/src/main/java/reactor/blockhound/NativeWrappingClassFileTransformer.java b/agent/src/main/java/reactor/blockhound/NativeWrappingClassFileTransformer.java index 7e72d40..f15d0ad 100644 --- a/agent/src/main/java/reactor/blockhound/NativeWrappingClassFileTransformer.java +++ b/agent/src/main/java/reactor/blockhound/NativeWrappingClassFileTransformer.java @@ -36,13 +36,7 @@ class NativeWrappingClassFileTransformer implements ClassFileTransformer { private final Map>> blockingMethods; - public static final boolean IS_JDK_18_OR_NEWER; - - static { - String javaVersion = System.getProperty("java.specification.version"); - double version = Double.parseDouble(javaVersion); - IS_JDK_18_OR_NEWER = version >= 18.0; - } + private static final int JDK_18 = 18; NativeWrappingClassFileTransformer(final Map>> blockingMethods) { this.blockingMethods = blockingMethods; @@ -116,7 +110,7 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str @Override public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { // See #392 - if (IS_JDK_18_OR_NEWER && descriptor.equals("Ljdk/internal/vm/annotation/IntrinsicCandidate;")) { + if (InstrumentationUtils.jdkMajorVersion >= JDK_18 && descriptor.equals("Ljdk/internal/vm/annotation/IntrinsicCandidate;")) { return null; // remove the intrinsic annotation } return super.visitAnnotation(descriptor, visible);