2

Byte Buddy 0.7.1 を使用して、Java (8) と Groovy (2.4.5) が混在するプロジェクトからクラスのメソッドへの呼び出しをインターセプトしようとしています。

のような特定のパッケージ内のクラスのメソッド呼び出しとその引数のための小さな「汎用ロギング フライト レコーダー」のようなものを作成するという考えですfoo

私は Byte BuddyAgentBuilderと私のカスタム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 クラスに対して正常に機能します。@CompileStaticまた、アノテーションを持つすべての Groovy クラスで正常に機能します。

java.lang.VerifyErrorしかし、奇妙なs のような古典的な (動的な) Groovy クラスでは失敗します

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 メソッドのインターセプトをサポートしていますか?

4

1 に答える 1