From 0759129c14788f733fa7f5b20a0028fb638d2f49 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Fri, 29 Nov 2024 14:44:02 +0100 Subject: [PATCH] Deprecate RuntimeHintsAgent Java agent This Java agent has been designed to instrument specific JDK calls for reflective introspection and invocations. This is useful for testing runtime hints in integration tests. As of GraalVM 23, there is a new VM option that does this in a much more efficient and precise fashion. Developers can use the `-XX:MissingRegistrationReportingMode` with the "Warn" or "Exit" value. The option will look for reachability metadata and emit logs in "Warn" mode or immediately exit the application with in "Exit" mode. This commit deprecates the `RuntimeHintsAgent` in favor of this new, more reliable option. See gh-33847 --- .../aot/agent/InstrumentedMethod.java | 55 +--- .../aot/agent/RuntimeHintsAgent.java | 3 + .../aot/test/agent/RuntimeHintsRecorder.java | 9 +- .../aot/agent/InstrumentedMethodTests.java | 304 ++++-------------- 4 files changed, 80 insertions(+), 291 deletions(-) diff --git a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java index 2c320d67e5..153a16e997 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java +++ b/spring-core-test/src/main/java/org/springframework/aot/agent/InstrumentedMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,13 +20,11 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.util.ResourceBundle; import java.util.function.Function; import java.util.function.Predicate; -import org.springframework.aot.hint.MemberCategory; import org.springframework.aot.hint.RuntimeHints; import org.springframework.aot.hint.TypeReference; import org.springframework.aot.hint.predicate.RuntimeHintsPredicates; @@ -67,8 +65,7 @@ enum InstrumentedMethod { CLASS_GETCLASSES(Class.class, "getClasses", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)) - .withAnyMemberCategory(MemberCategory.DECLARED_CLASSES, MemberCategory.PUBLIC_CLASSES); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -81,7 +78,7 @@ enum InstrumentedMethod { if (constructor == null) { return runtimeHints -> false; } - return reflection().onConstructor(constructor).introspect(); + return reflection().onType(constructor.getDeclaringClass()); } ), @@ -91,9 +88,7 @@ enum InstrumentedMethod { CLASS_GETCONSTRUCTORS(Class.class, "getConstructors", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)).withAnyMemberCategory( - MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, - MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -103,7 +98,7 @@ enum InstrumentedMethod { CLASS_GETDECLAREDCLASSES(Class.class, "getDeclaredClasses", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)).withMemberCategory(MemberCategory.DECLARED_CLASSES); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -116,9 +111,7 @@ enum InstrumentedMethod { if (constructor == null) { return runtimeHints -> false; } - TypeReference thisType = invocation.getInstanceTypeReference(); - return reflection().onType(thisType).withMemberCategory(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS) - .or(reflection().onConstructor(constructor).introspect()); + return reflection().onType(constructor.getDeclaringClass()); } ), @@ -128,8 +121,7 @@ enum InstrumentedMethod { CLASS_GETDECLAREDCONSTRUCTORS(Class.class, "getDeclaredConstructors", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)) - .withAnyMemberCategory(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); + return reflection().onType(TypeReference.of(thisClass)); }), /** @@ -141,9 +133,7 @@ enum InstrumentedMethod { if (field == null) { return runtimeHints -> false; } - TypeReference thisType = invocation.getInstanceTypeReference(); - return reflection().onType(thisType).withMemberCategory(MemberCategory.DECLARED_FIELDS) - .or(reflection().onField(field)); + return reflection().onType(field.getDeclaringClass()); } ), @@ -153,7 +143,7 @@ enum InstrumentedMethod { CLASS_GETDECLAREDFIELDS(Class.class, "getDeclaredFields", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)).withMemberCategory(MemberCategory.DECLARED_FIELDS); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -166,10 +156,7 @@ enum InstrumentedMethod { if (method == null) { return runtimeHints -> false; } - TypeReference thisType = invocation.getInstanceTypeReference(); - return reflection().onType(thisType) - .withAnyMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_METHODS) - .or(reflection().onMethod(method).introspect()); + return reflection().onType(method.getDeclaringClass()); } ), @@ -179,8 +166,7 @@ enum InstrumentedMethod { CLASS_GETDECLAREDMETHODS(Class.class, "getDeclaredMethods", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)) - .withAnyMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_METHODS); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -194,10 +180,7 @@ enum InstrumentedMethod { if (field == null) { return runtimeHints -> false; } - TypeReference thisType = invocation.getInstanceTypeReference(); - return reflection().onType(thisType).withMemberCategory(MemberCategory.PUBLIC_FIELDS) - .and(runtimeHints -> Modifier.isPublic(field.getModifiers())) - .or(reflection().onType(thisType).withMemberCategory(MemberCategory.DECLARED_FIELDS)) + return reflection().onType(field.getDeclaringClass()) .or(reflection().onField(invocation.getReturnValue())); }), @@ -207,8 +190,7 @@ enum InstrumentedMethod { CLASS_GETFIELDS(Class.class, "getFields", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)) - .withAnyMemberCategory(MemberCategory.PUBLIC_FIELDS, MemberCategory.DECLARED_FIELDS); + return reflection().onType(TypeReference.of(thisClass)); } ), @@ -221,12 +203,7 @@ enum InstrumentedMethod { if (method == null) { return runtimeHints -> false; } - TypeReference thisType = invocation.getInstanceTypeReference(); - return reflection().onType(thisType).withAnyMemberCategory(MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INVOKE_PUBLIC_METHODS) - .and(runtimeHints -> Modifier.isPublic(method.getModifiers())) - .or(reflection().onType(thisType).withAnyMemberCategory(MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_METHODS)) - .or(reflection().onMethod(method).introspect()) - .or(reflection().onMethod(method).invoke()); + return reflection().onType(method.getDeclaringClass()); } ), @@ -236,9 +213,7 @@ enum InstrumentedMethod { CLASS_GETMETHODS(Class.class, "getMethods", HintType.REFLECTION, invocation -> { Class thisClass = invocation.getInstance(); - return reflection().onType(TypeReference.of(thisClass)).withAnyMemberCategory( - MemberCategory.INTROSPECT_PUBLIC_METHODS, MemberCategory.INTROSPECT_DECLARED_METHODS, - MemberCategory.INVOKE_PUBLIC_METHODS, MemberCategory.INVOKE_DECLARED_METHODS); + return reflection().onType(TypeReference.of(thisClass)); } ), diff --git a/spring-core-test/src/main/java/org/springframework/aot/agent/RuntimeHintsAgent.java b/spring-core-test/src/main/java/org/springframework/aot/agent/RuntimeHintsAgent.java index 375fdb2dba..e03f71de77 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/agent/RuntimeHintsAgent.java +++ b/spring-core-test/src/main/java/org/springframework/aot/agent/RuntimeHintsAgent.java @@ -39,7 +39,10 @@ import org.springframework.util.StringUtils; * @author Brian Clozel * @since 6.0 * @see InvocationsRecorderClassTransformer + * @deprecated as of 7.0 in favor of the {@code -XX:MissingRegistrationReportingMode=Warn} and + * {@code -XX:MissingRegistrationReportingMode=Exit} JVM flags with GraalVM. */ +@Deprecated(forRemoval = true) public final class RuntimeHintsAgent { private static boolean loaded = false; diff --git a/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsRecorder.java b/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsRecorder.java index 50faf662d4..b6471174ff 100644 --- a/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsRecorder.java +++ b/spring-core-test/src/main/java/org/springframework/aot/test/agent/RuntimeHintsRecorder.java @@ -22,17 +22,20 @@ import java.util.Deque; import org.springframework.aot.agent.RecordedInvocation; import org.springframework.aot.agent.RecordedInvocationsListener; import org.springframework.aot.agent.RecordedInvocationsPublisher; -import org.springframework.aot.agent.RuntimeHintsAgent; import org.springframework.aot.hint.RuntimeHints; import org.springframework.util.Assert; /** * Invocations relevant to {@link RuntimeHints} recorded during the execution of a block - * of code instrumented by the {@link RuntimeHintsAgent}. + * of code instrumented by the {@link org.springframework.aot.agent.RuntimeHintsAgent}. * * @author Brian Clozel * @since 6.0 + * @deprecated as of 7.0 in favor of the {@code -XX:MissingRegistrationReportingMode=Warn} and + * {@code -XX:MissingRegistrationReportingMode=Exit} JVM flags with GraalVM. */ +@Deprecated(forRemoval = true) +@SuppressWarnings("removal") public final class RuntimeHintsRecorder { private final RuntimeHintsInvocationsListener listener; @@ -49,7 +52,7 @@ public final class RuntimeHintsRecorder { */ public static synchronized RuntimeHintsInvocations record(Runnable action) { Assert.notNull(action, "Runnable action must not be null"); - Assert.state(RuntimeHintsAgent.isLoaded(), "RuntimeHintsAgent must be loaded in the current JVM"); + Assert.state(org.springframework.aot.agent.RuntimeHintsAgent.isLoaded(), "RuntimeHintsAgent must be loaded in the current JVM"); RuntimeHintsRecorder recorder = new RuntimeHintsRecorder(); RecordedInvocationsPublisher.addListener(recorder.listener); try { diff --git a/spring-core-test/src/test/java/org/springframework/aot/agent/InstrumentedMethodTests.java b/spring-core-test/src/test/java/org/springframework/aot/agent/InstrumentedMethodTests.java index 48a9b68652..70a86c6f0d 100644 --- a/spring-core-test/src/test/java/org/springframework/aot/agent/InstrumentedMethodTests.java +++ b/spring-core-test/src/test/java/org/springframework/aot/agent/InstrumentedMethodTests.java @@ -61,32 +61,26 @@ class InstrumentedMethodTests { } @Test - void classGetClassesShouldNotMatchReflectionOnType() { + void classForNameShouldNotMatchWhenMissingReflectionOnType() { + RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_FORNAME) + .withArgument("java.lang.String").returnValue(String.class).build(); + assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_FORNAME, invocation); + } + + @Test + void classGetClassesShouldMatchReflectionOnType() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETCLASSES, this.stringGetClasses); - } - - @Test - void classGetClassesShouldMatchPublicClasses() { - hints.reflection().registerType(String.class, MemberCategory.PUBLIC_CLASSES); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCLASSES, this.stringGetClasses); } @Test - void classGetClassesShouldMatchDeclaredClasses() { - hints.reflection().registerType(String.class, MemberCategory.DECLARED_CLASSES); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCLASSES, this.stringGetClasses); - } - - @Test - void classGetDeclaredClassesShouldMatchDeclaredClassesHint() { - hints.reflection().registerType(String.class, MemberCategory.DECLARED_CLASSES); + void classGetDeclaredClassesShouldMatchReflectionOnType() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCLASSES, this.stringGetDeclaredClasses); } @Test - void classGetDeclaredClassesShouldNotMatchPublicClassesHint() { - hints.reflection().registerType(String.class, MemberCategory.PUBLIC_CLASSES); + void classGetDeclaredClassesShouldNotMatchWhenMissingReflectionOnType() { assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDCLASSES, this.stringGetDeclaredClasses); } @@ -124,36 +118,28 @@ class InstrumentedMethodTests { } @Test - void classGetConstructorShouldMatchIntrospectPublicConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS); + void classGetConstructorShouldMatchTypeHint() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); } + @Test + void classGetConstructorShouldNotMatchWhenMissingTypeHint() { + assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); + } + @Test void classGetConstructorShouldMatchInvokePublicConstructorsHint() { hints.reflection().registerType(String.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); } - @Test - void classGetConstructorShouldMatchIntrospectDeclaredConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); - } - @Test void classGetConstructorShouldMatchInvokeDeclaredConstructorsHint() { hints.reflection().registerType(String.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); } - @Test - void classGetConstructorShouldMatchIntrospectConstructorHint() { - hints.reflection().registerType(String.class,typeHint -> - typeHint.withConstructor(Collections.emptyList(), ExecutableMode.INTROSPECT)); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTOR, this.stringGetConstructor); - } - @Test void classGetConstructorShouldMatchInvokeConstructorHint() { hints.reflection().registerType(String.class, typeHint -> @@ -162,23 +148,22 @@ class InstrumentedMethodTests { } @Test - void classGetConstructorsShouldMatchIntrospectPublicConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS); + void classGetConstructorsShouldMatchTypeHint() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); } + @Test + void classGetConstructorsShouldNotMatchWhemMissingTypeHint() { + assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); + } + @Test void classGetConstructorsShouldMatchInvokePublicConstructorsHint() { hints.reflection().registerType(String.class, MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); } - @Test - void classGetConstructorsShouldMatchIntrospectDeclaredConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); - } - @Test void classGetConstructorsShouldMatchInvokeDeclaredConstructorsHint() { hints.reflection().registerType(String.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); @@ -186,36 +171,16 @@ class InstrumentedMethodTests { } @Test - void classGetConstructorsShouldNotMatchTypeReflectionHint() { + void classGetDeclaredConstructorShouldMatchTypeHint() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); - } - - @Test - void classGetConstructorsShouldNotMatchConstructorReflectionHint() throws Exception { - hints.reflection().registerConstructor(String.class.getConstructor(), ExecutableMode.INVOKE); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETCONSTRUCTORS, this.stringGetConstructors); - } - - @Test - void classGetDeclaredConstructorShouldMatchIntrospectDeclaredConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTOR, this.stringGetDeclaredConstructor); } @Test - void classGetDeclaredConstructorShouldNotMatchIntrospectPublicConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS); + void classGetDeclaredConstructorShouldNotMatchWhenMissingTypeHint() { assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTOR, this.stringGetDeclaredConstructor); } - @Test - void classGetDeclaredConstructorShouldMatchIntrospectConstructorHint() { - hints.reflection().registerType(String.class, typeHint -> - typeHint.withConstructor(TypeReference.listOf(byte[].class, byte.class), ExecutableMode.INTROSPECT)); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTOR, this.stringGetDeclaredConstructor); - } - @Test void classGetDeclaredConstructorShouldMatchInvokeConstructorHint() { hints.reflection().registerType(String.class, typeHint -> @@ -223,12 +188,6 @@ class InstrumentedMethodTests { assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTOR, this.stringGetDeclaredConstructor); } - @Test - void classGetDeclaredConstructorsShouldMatchIntrospectDeclaredConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors); - } - @Test void classGetDeclaredConstructorsShouldMatchInvokeDeclaredConstructorsHint() { hints.reflection().registerType(String.class, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS); @@ -236,20 +195,13 @@ class InstrumentedMethodTests { } @Test - void classGetDeclaredConstructorsShouldNotMatchIntrospectPublicConstructorsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_CONSTRUCTORS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors); - } - - @Test - void classGetDeclaredConstructorsShouldNotMatchTypeReflectionHint() { + void classGetDeclaredConstructorsShouldMatchTypeReflectionHint() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors); + assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors); } @Test - void classGetDeclaredConstructorsShouldNotMatchConstructorReflectionHint() throws Exception { - hints.reflection().registerConstructor(String.class.getConstructor(), ExecutableMode.INVOKE); + void classGetDeclaredConstructorsShouldNotMatchWhenMissingTypeReflectionHint() { assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDCONSTRUCTORS, this.stringGetDeclaredConstructors); } @@ -262,15 +214,6 @@ class InstrumentedMethodTests { assertThatInvocationMatches(InstrumentedMethod.CONSTRUCTOR_NEWINSTANCE, invocation); } - @Test - void constructorNewInstanceShouldNotMatchIntrospectHintOnConstructor() throws NoSuchMethodException { - RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CONSTRUCTOR_NEWINSTANCE) - .onInstance(String.class.getConstructor()).returnValue("").build(); - hints.reflection().registerType(String.class, typeHint -> - typeHint.withConstructor(Collections.emptyList(), ExecutableMode.INTROSPECT)); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CONSTRUCTOR_NEWINSTANCE, invocation); - } - } @Nested @@ -295,22 +238,8 @@ class InstrumentedMethodTests { } @Test - void classGetDeclaredMethodShouldMatchIntrospectDeclaredMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHOD, this.stringGetScaleMethod); - } - - @Test - void classGetDeclaredMethodShouldNotMatchIntrospectPublicMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDMETHOD, this.stringGetScaleMethod); - } - - @Test - void classGetDeclaredMethodShouldMatchIntrospectMethodHint() { - List parameterTypes = TypeReference.listOf(int.class, float.class); - hints.reflection().registerType(String.class, typeHint -> - typeHint.withMethod("scale", parameterTypes, ExecutableMode.INTROSPECT)); + void classGetDeclaredMethodShouldMatchTypeReflectionHint() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHOD, this.stringGetScaleMethod); } @@ -322,12 +251,6 @@ class InstrumentedMethodTests { assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHOD, this.stringGetScaleMethod); } - @Test - void classGetDeclaredMethodsShouldMatchIntrospectDeclaredMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod); - } - @Test void classGetDeclaredMethodsShouldMatchInvokeDeclaredMethodsHint() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETDECLAREDMETHODS).onInstance(String.class).build(); @@ -336,32 +259,8 @@ class InstrumentedMethodTests { } @Test - void classGetDeclaredMethodsShouldNotMatchIntrospectPublicMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod); - } - - @Test - void classGetDeclaredMethodsShouldNotMatchTypeReflectionHint() { + void classGetMethodsShouldMatchTypeReflectionHint() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod); - } - - @Test - void classGetDeclaredMethodsShouldNotMatchMethodReflectionHint() throws Exception { - hints.reflection().registerMethod(String.class.getMethod("toString"), ExecutableMode.INVOKE); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDMETHODS, this.stringGetScaleMethod); - } - - @Test - void classGetMethodsShouldMatchIntrospectDeclaredMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods); - } - - @Test - void classGetMethodsShouldMatchIntrospectPublicMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods); } @@ -379,25 +278,13 @@ class InstrumentedMethodTests { @Test void classGetMethodsShouldNotMatchForWrongType() { - hints.reflection().registerType(Integer.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); + hints.reflection().registerType(Integer.class); assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods); } @Test - void classGetMethodsShouldNotMatchTypeReflectionHint() { + void classGetMethodShouldMatchReflectionTypeHint() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods); - } - - @Test - void classGetMethodsShouldNotMatchMethodReflectionHint() throws Exception { - hints.reflection().registerMethod(String.class.getMethod("toString"), ExecutableMode.INVOKE); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHODS, this.stringGetMethods); - } - - @Test - void classGetMethodShouldMatchIntrospectPublicMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); } @@ -407,25 +294,6 @@ class InstrumentedMethodTests { assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); } - @Test - void classGetMethodShouldNotMatchIntrospectDeclaredMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); - } - - @Test - void classGetMethodShouldNotMatchInvokeDeclaredMethodsHint() { - hints.reflection().registerType(String.class, MemberCategory.INVOKE_DECLARED_METHODS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); - } - - @Test - void classGetMethodShouldMatchIntrospectMethodHint() { - hints.reflection().registerType(String.class, typeHint -> - typeHint.withMethod("toString", Collections.emptyList(), ExecutableMode.INTROSPECT)); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); - } - @Test void classGetMethodShouldMatchInvokeMethodHint() { hints.reflection().registerType(String.class, typeHint -> @@ -433,21 +301,9 @@ class InstrumentedMethodTests { assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); } - @Test - void classGetMethodShouldNotMatchIntrospectPublicMethodsHintWhenPrivate() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetScaleMethod); - } - - @Test - void classGetMethodShouldMatchIntrospectDeclaredMethodsHintWhenPrivate() { - hints.reflection().registerType(String.class, MemberCategory.INTROSPECT_DECLARED_METHODS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetScaleMethod); - } - @Test void classGetMethodShouldNotMatchForWrongType() { - hints.reflection().registerType(Integer.class, MemberCategory.INTROSPECT_PUBLIC_METHODS); + hints.reflection().registerType(Integer.class); assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETMETHOD, this.stringGetToStringMethod); } @@ -461,11 +317,10 @@ class InstrumentedMethodTests { } @Test - void methodInvokeShouldNotMatchIntrospectHintOnMethod() throws NoSuchMethodException { + void methodInvokeShouldNotMatchReflectionTypeHint() throws NoSuchMethodException { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.METHOD_INVOKE) .onInstance(String.class.getMethod("toString")).withArguments("", new Object[0]).build(); - hints.reflection().registerType(String.class, typeHint -> - typeHint.withMethod("toString", Collections.emptyList(), ExecutableMode.INTROSPECT)); + hints.reflection().registerType(String.class); assertThatInvocationDoesNotMatch(InstrumentedMethod.METHOD_INVOKE, invocation); } @@ -496,17 +351,11 @@ class InstrumentedMethodTests { } @Test - void classGetDeclaredFieldShouldMatchDeclaredFieldsHint() { - hints.reflection().registerType(String.class, MemberCategory.DECLARED_FIELDS); + void classGetDeclaredFieldShouldMatchTypeReflectionHint() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDFIELD, this.stringGetDeclaredField); } - @Test - void classGetDeclaredFieldShouldNotMatchPublicFieldsHint() { - hints.reflection().registerType(String.class, typeHint -> typeHint.withMembers(MemberCategory.PUBLIC_FIELDS)); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDFIELD, this.stringGetDeclaredField); - } - @Test void classGetDeclaredFieldShouldMatchFieldHint() { hints.reflection().registerType(String.class, typeHint -> typeHint.withField("value")); @@ -514,41 +363,23 @@ class InstrumentedMethodTests { } @Test - void classGetDeclaredFieldsShouldMatchDeclaredFieldsHint() { - hints.reflection().registerType(String.class, MemberCategory.DECLARED_FIELDS); + void classGetDeclaredFieldsShouldMatchTypeReflectionHint() { + hints.reflection().registerType(String.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDFIELDS, this.stringGetDeclaredFields); } @Test - void classGetDeclaredFieldsShouldNotMatchPublicFieldsHint() { - hints.reflection().registerType(String.class, MemberCategory.PUBLIC_FIELDS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDFIELDS, this.stringGetDeclaredFields); - } - - @Test - void classGetDeclaredFieldsShouldNotMatchTypeHint() { - hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDFIELDS, this.stringGetDeclaredFields); - } - - @Test - void classGetDeclaredFieldsShouldNotMatchFieldHint() throws Exception { + void classGetDeclaredFieldsShouldMatchFieldHint() throws Exception { hints.reflection().registerField(String.class.getDeclaredField("value")); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETDECLAREDFIELDS, this.stringGetDeclaredFields); + assertThatInvocationMatches(InstrumentedMethod.CLASS_GETDECLAREDFIELDS, this.stringGetDeclaredFields); } @Test - void classGetFieldShouldMatchPublicFieldsHint() { - hints.reflection().registerType(PublicField.class, MemberCategory.PUBLIC_FIELDS); + void classGetFieldShouldMatchTypeReflectionHint() { + hints.reflection().registerType(PublicField.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELD, this.getPublicField); } - @Test - void classGetFieldShouldNotMatchDeclaredFieldsHint() { - hints.reflection().registerType(PublicField.class, MemberCategory.DECLARED_FIELDS); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELD, this.getPublicField); - } - @Test void classGetFieldShouldMatchFieldHint() { hints.reflection().registerType(PublicField.class, typeHint -> typeHint.withField("field")); @@ -559,53 +390,30 @@ class InstrumentedMethodTests { void classGetFieldShouldNotMatchPublicFieldsHintWhenPrivate() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETFIELD) .onInstance(String.class).withArgument("value").returnValue(null).build(); - hints.reflection().registerType(String.class, MemberCategory.PUBLIC_FIELDS); + hints.reflection().registerType(String.class); assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELD, invocation); } - @Test - void classGetFieldShouldMatchDeclaredFieldsHintWhenPrivate() throws NoSuchFieldException { - RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETFIELD) - .onInstance(String.class).withArgument("value").returnValue(String.class.getDeclaredField("value")).build(); - hints.reflection().registerType(String.class, MemberCategory.DECLARED_FIELDS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELD, invocation); - } - @Test void classGetFieldShouldNotMatchForWrongType() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETFIELD) .onInstance(String.class).withArgument("value").returnValue(null).build(); - hints.reflection().registerType(Integer.class, MemberCategory.DECLARED_FIELDS); + hints.reflection().registerType(Integer.class); assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELD, invocation); } @Test - void classGetFieldsShouldMatchPublicFieldsHint() { + void classGetFieldsShouldMatchReflectionHint() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETFIELDS) .onInstance(PublicField.class).build(); - hints.reflection().registerType(PublicField.class, MemberCategory.PUBLIC_FIELDS); + hints.reflection().registerType(PublicField.class); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELDS, invocation); } @Test - void classGetFieldsShouldMatchDeclaredFieldsHint() { - RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETFIELDS) - .onInstance(PublicField.class).build(); - hints.reflection().registerType(PublicField.class, MemberCategory.DECLARED_FIELDS); - assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELDS, invocation); - } - - - @Test - void classGetFieldsShouldNotMatchTypeHint() { + void classGetFieldsShouldMatchTypeHint() { hints.reflection().registerType(String.class); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELDS, this.stringGetFields); - } - - @Test - void classGetFieldsShouldNotMatchFieldHint() throws Exception { - hints.reflection().registerField(String.class.getDeclaredField("value")); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETFIELDS, this.stringGetFields); + assertThatInvocationMatches(InstrumentedMethod.CLASS_GETFIELDS, this.stringGetFields); } } @@ -634,7 +442,7 @@ class InstrumentedMethodTests { void classGetResourceShouldMatchResourcePatternWhenAbsolute() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETRESOURCE) .onInstance(InstrumentedMethodTests.class).withArgument("/some/path/resource.txt").build(); - hints.resources().registerPattern("some/*"); + hints.resources().registerPattern("some/**"); assertThatInvocationMatches(InstrumentedMethod.CLASS_GETRESOURCE, invocation); } @@ -655,11 +463,11 @@ class InstrumentedMethodTests { } @Test - void classGetResourceShouldNotMatchResourcePatternWhenExcluded() { + void classGetResourceShouldMatchWhenGlobPattern() { RecordedInvocation invocation = RecordedInvocation.of(InstrumentedMethod.CLASS_GETRESOURCE) .onInstance(InstrumentedMethodTests.class).withArgument("/some/path/resource.txt").build(); - hints.resources().registerPattern(resourceHint -> resourceHint.includes("some/*").excludes("some/path/*")); - assertThatInvocationDoesNotMatch(InstrumentedMethod.CLASS_GETRESOURCE, invocation); + hints.resources().registerPattern(resourceHint -> resourceHint.includes("some/**")); + assertThatInvocationMatches(InstrumentedMethod.CLASS_GETRESOURCE, invocation); } }