Я пытаюсь перехватить вызовы методов классов из смешанного проекта Java (8) и Groovy (2.4.5), используя Byte Buddy 0.7.1.
Идея состоит в том, чтобы создать что-то вроде небольшого «общего регистратора полетов» для вызовов методов и их аргументов для классов в конкретном пакете, таком как foo
.
Я использую Byte Buddy AgentBuilder
и свой собственный LogInterceptor
, чтобы сделать это при запуске приложения:
static {
final Instrumentation inst = ByteBuddyAgent.install();
new AgentBuilder.Default()
.type(ElementMatchers.nameContainsIgnoreCase("foo")) // simplified
.transform((builder, typeDescription) ->
builder.method(ElementMatchers.any())
.intercept(MethodDelegation.to(LogInterceptor.class)
.andThen(SuperMethodCall.INSTANCE)))
.installOn(inst);
}
public static class LogInterceptor {
@RuntimeType
public static void log(@Origin Method method, @AllArguments Object[] arg) throws Exception {
// flightRecorder.log(...);
}
}
Перехват метода отлично работает для всех классов Java. И он отлично работает для всех классов Groovy с аннотацией @CompileStatic
.
Но это не работает для классических (динамических) классов Groovy со странными java.lang.VerifyError
, такими как
java.lang.VerifyError: (class: foo/MyInterceptedClass$barMethod, method: <clinit> signature: ()V) Illegal type in constant pool
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.getConstructor(Class.java:1825)
at org.codehaus.groovy.reflection.ClassLoaderForClassArtifacts.defineClassAndGetConstructor(ClassLoaderForClassArtifacts.java:83)
at org.codehaus.groovy.runtime.callsite.CallSiteGenerator.compileStaticMethod(CallSiteGenerator.java:246)
at org.codehaus.groovy.reflection.CachedMethod.createStaticMetaMethodSite(CachedMethod.java:288)
at org.codehaus.groovy.runtime.callsite.StaticMetaMethodSite.createStaticMetaMethodSite(StaticMetaMethodSite.java:114)
at groovy.lang.MetaClassImpl.createStaticSite(MetaClassImpl.java:3385)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallStaticSite(CallSiteArray.java:77)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:162)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:133)
...
Что тут происходит? Поддерживает ли Byte Buddy перехват методов Groovy?