Skip to content

Commit 181af5c

Browse files
committed
Fix: methodkey for target function must use the method declaring class
1 parent 5e3fed0 commit 181af5c

File tree

2 files changed

+67
-33
lines changed

2 files changed

+67
-33
lines changed

libs/entitlement/asm-provider/src/main/java/org/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImpl.java

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ public InstrumentationInfo lookupImplementationMethod(
118118
) throws NoSuchMethodException, ClassNotFoundException {
119119

120120
var targetMethod = targetSuperclass.getDeclaredMethod(methodName, parameterTypes);
121-
validateTargetMethod(implementationClass, targetMethod);
121+
var implementationMethod = implementationClass.getMethod(targetMethod.getName(), targetMethod.getParameterTypes());
122+
validateTargetMethod(implementationClass, targetMethod, implementationMethod);
122123

123124
var checkerAdditionalArguments = Stream.of(Class.class, targetSuperclass);
124125
var checkMethodArgumentTypes = Stream.concat(checkerAdditionalArguments, Arrays.stream(parameterTypes))
@@ -169,15 +170,15 @@ public MethodVisitor visitMethod(
169170

170171
return new InstrumentationInfo(
171172
new MethodKey(
172-
Type.getInternalName(implementationClass),
173-
targetMethod.getName(),
173+
Type.getInternalName(implementationMethod.getDeclaringClass()),
174+
implementationMethod.getName(),
174175
Arrays.stream(parameterTypes).map(c -> Type.getType(c).getInternalName()).toList()
175176
),
176177
checkMethod[0]
177178
);
178179
}
179180

180-
private static void validateTargetMethod(Class<?> implementationClass, Method targetMethod) {
181+
private static void validateTargetMethod(Class<?> implementationClass, Method targetMethod, Method implementationMethod) {
181182
if (targetMethod.getDeclaringClass().isAssignableFrom(implementationClass) == false) {
182183
throw new IllegalArgumentException(
183184
String.format(
@@ -209,37 +210,26 @@ private static void validateTargetMethod(Class<?> implementationClass, Method ta
209210
)
210211
);
211212
}
212-
try {
213-
var implementationMethod = implementationClass.getMethod(targetMethod.getName(), targetMethod.getParameterTypes());
214-
var methodModifiers = implementationMethod.getModifiers();
215-
if (Modifier.isAbstract(methodModifiers)) {
216-
throw new IllegalArgumentException(
217-
String.format(
218-
Locale.ROOT,
219-
"Not a valid instrumentation method: %s is abstract in %s",
220-
targetMethod.getName(),
221-
implementationClass.getName()
222-
)
223-
);
224-
}
225-
if (Modifier.isPublic(methodModifiers) == false) {
226-
throw new IllegalArgumentException(
227-
String.format(
228-
Locale.ROOT,
229-
"Not a valid instrumentation method: %s is not public in %s",
230-
targetMethod.getName(),
231-
implementationClass.getName()
232-
)
233-
);
234-
}
235-
} catch (NoSuchMethodException e) {
236-
assert false
237-
: String.format(
213+
var methodModifiers = implementationMethod.getModifiers();
214+
if (Modifier.isAbstract(methodModifiers)) {
215+
throw new IllegalArgumentException(
216+
String.format(
238217
Locale.ROOT,
239-
"Not a valid instrumentation method: %s cannot be found in %s",
218+
"Not a valid instrumentation method: %s is abstract in %s",
240219
targetMethod.getName(),
241220
implementationClass.getName()
242-
);
221+
)
222+
);
223+
}
224+
if (Modifier.isPublic(methodModifiers) == false) {
225+
throw new IllegalArgumentException(
226+
String.format(
227+
Locale.ROOT,
228+
"Not a valid instrumentation method: %s is not public in %s",
229+
targetMethod.getName(),
230+
implementationClass.getName()
231+
)
232+
);
243233
}
244234
}
245235

libs/entitlement/asm-provider/src/test/java/org/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImplTests.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,15 @@ public void instanceMethod(int x, String y) {}
4040

4141
abstract static class TestTargetBaseClass {
4242
abstract void instanceMethod(int x, String y);
43+
abstract void instanceMethod2(int x, String y);
4344
}
4445

45-
static class TestTargetImplementationClass extends TestTargetBaseClass {
46+
abstract static class TestTargetIntermediateClass extends TestTargetBaseClass {
47+
@Override
48+
public void instanceMethod2(int x, String y) {}
49+
}
50+
51+
static class TestTargetImplementationClass extends TestTargetIntermediateClass {
4652
@Override
4753
public void instanceMethod(int x, String y) {}
4854
}
@@ -364,6 +370,44 @@ public void testLookupImplementationMethodWithBaseClass() throws ClassNotFoundEx
364370
);
365371
}
366372

373+
public void testLookupImplementationMethodWithInheritance() throws ClassNotFoundException, NoSuchMethodException {
374+
var info = instrumentationService.lookupImplementationMethod(
375+
TestTargetBaseClass.class,
376+
"instanceMethod2",
377+
TestTargetImplementationClass.class,
378+
TestCheckerMixed.class,
379+
"checkInstanceMethodManual",
380+
int.class,
381+
String.class
382+
);
383+
384+
assertThat(
385+
info.targetMethod(),
386+
equalTo(
387+
new MethodKey(
388+
"org/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImplTests$TestTargetIntermediateClass",
389+
"instanceMethod2",
390+
List.of("I", "java/lang/String")
391+
)
392+
)
393+
);
394+
assertThat(
395+
info.checkMethod(),
396+
equalTo(
397+
new CheckMethod(
398+
"org/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImplTests$TestCheckerMixed",
399+
"checkInstanceMethodManual",
400+
List.of(
401+
"Ljava/lang/Class;",
402+
"Lorg/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImplTests$TestTargetBaseClass;",
403+
"I",
404+
"Ljava/lang/String;"
405+
)
406+
)
407+
)
408+
);
409+
}
410+
367411
public void testParseCheckerMethodSignatureStaticMethod() {
368412
var methodKey = InstrumentationServiceImpl.parseCheckerMethodSignature(
369413
"check$org_example_TestClass$$staticMethod",

0 commit comments

Comments
 (0)