2017-12-14 5 views
0

長時間開いている接続を監視するために、java.sql.Connection型のサブクラスにフィールドを追加しようとしています(例えば接続漏れ)。クラスにフィールドを追加すると、 "<constructor>はインデックス2を定義しません"

これは私が実行しようとしていますものです:

public class TransactionMonitorVisitor { 

    interface FieldSetter { 
     void setField(String value); 
    } 

    interface FieldGetter { 
     String getValue(); 
    } 

    public static class ConnectionConstructorVisitor { 
     @Advice.OnMethodExit 
     public static void intercept(@Advice.Origin Constructor<?> constructor, 
            @Advice.This Object obj, 
            @FieldProxy("__txUuid__") FieldSetter accessor 
     ) { 
      String txUuid = UUID.randomUUID().toString(); 

      System.out.println("Visiting constructor: txUuid=" + txUuid + ", obj=" + obj); 
      accessor.setField(txUuid); 
     } 
    } 

    public static class ConnectionMethodVisitor { 
     @Advice.OnMethodExit 
     public static void intercept(@Advice.Origin Method method, 
            @FieldProxy("__txUuid__") FieldGetter accessor 
     ) { 
      String methodName = method.getName(); 
      String txUuid = accessor.getValue(); 

      System.out.println("Visiting method: txUuid=" + txUuid + ", method=" + methodName); 
     } 
    } 

    public static void installOn(Instrumentation instrumentation) throws Exception { 
     new AgentBuilder.Default() 
       .type(ElementMatchers.isSubTypeOf(Connection.class)) 
       .transform((builder, typeDescription, classLoader, javaModule) -> 
         builder.defineField("__txUuid__", String.class) 
          .visit(Advice.to(ConnectionConstructorVisitor.class).on((ElementMatchers.isConstructor()))) 
          .visit(Advice.to(ConnectionMethodVisitor.class).on(ElementMatchers.nameMatches("commit|rollback|close"))) 
       ) 
       .with(AgentBuilder.Listener.StreamWriting.toSystemError()) 
       .installOn(instrumentation); 

     System.out.println("Installed :: " + TransactionMonitorVisitor.class.getName()); 
    } 
} 

私は自分のアプリケーション(Tomcatの中のWebアプリ)を起動すると、私は次のエラーを取得:いくつかの研究に基づいて

java.lang.IllegalStateException: net.sourceforge.jtds.jdbc.ConnectionJDBC3(java.lang.String,java.util.Properties) throws java.sql.SQLException does not define an index 2 
    at net.bytebuddy.asm.Advice$OffsetMapping$ForArgument$Unresolved.resolve(Advice.java:1551) 
    at net.bytebuddy.asm.Advice$OffsetMapping$ForArgument.resolve(Advice.java:1462) 
    at net.bytebuddy.asm.Advice$OffsetMapping$ForArgument$Unresolved.resolve(Advice.java:1564) 
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$ForMethodExit.apply(Advice.java:5818) 
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.visitMethod(Advice.java:5414) 
    at net.bytebuddy.jar.asm.ClassReader.b(Unknown Source) 
    at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source) 
    at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source) 
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$AdviceMethodInliner.doApply(Advice.java:5408) 
    at net.bytebuddy.asm.Advice$Dispatcher$Inlining$Resolved$ForMethodExit$AdviceMethodInliner.apply(Advice.java:5902) 
    at net.bytebuddy.asm.Advice$AdviceVisitor$WithExitAdvice.onUserEnd(Advice.java:7503) 
    at net.bytebuddy.asm.Advice$AdviceVisitor.visitMaxs(Advice.java:7251) 
    at net.bytebuddy.jar.asm.ClassReader.a(Unknown Source) 
    at net.bytebuddy.jar.asm.ClassReader.b(Unknown Source) 
    at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source) 
    at net.bytebuddy.jar.asm.ClassReader.accept(Unknown Source) 
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:2941) 
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1633) 
    at net.bytebuddy.dynamic.scaffold.inline.RebaseDynamicTypeBuilder.make(RebaseDynamicTypeBuilder.java:200) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$Transformation$Simple$Resolution.apply(AgentBuilder.java:8902) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:9303) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:9266) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1300(AgentBuilder.java:9044) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:9622) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:9572) 
    at ... 

を、私は.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)を追加しようとしましたが、それは上記と同じエラーが表示されます。

と組み合わせて.disableClassFormatChanges()を使用していた別の場所を見ましたが、それでもエラーが発生しません。新しいエラーは次のとおりです。

java.lang.IllegalStateException: Cannot define field for frozen type: class net.sourceforge.jtds.jdbc.ConnectionJDBC3 
    at net.bytebuddy.dynamic.scaffold.InstrumentedType$Frozen.withField(InstrumentedType.java:1149) 
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Adapter$FieldDefinitionAdapter.materialize(DynamicType.java:3159) 
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.visit(DynamicType.java:2571) 
    at com.calabrio.athena.tx.TransactionMonitorVisitor.lambda$installOn$0(TransactionMonitorVisitor.java:70) 
    at com.calabrio.athena.tx.TransactionMonitorVisitor$$Lambda$1/1528637575.transform(Unknown Source) 
    at net.bytebuddy.agent.builder.AgentBuilder$Transformer$Compound.transform(AgentBuilder.java:2335) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$Transformation$Simple$Resolution.apply(AgentBuilder.java:8899) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.doTransform(AgentBuilder.java:9303) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.transform(AgentBuilder.java:9266) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer.access$1300(AgentBuilder.java:9044) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:9622) 
    at net.bytebuddy.agent.builder.AgentBuilder$Default$ExecutingTransformer$LegacyVmDispatcher.run(AgentBuilder.java:9572) 

私がしようとしていることは可能ですか?もしそうなら、私は行方不明になっていますか?

答えて

0

フィールドプロキシは、アドバイスではなくMethodDelegationでのみ使用できます。アドバイスの場合、カスタム注釈をフィールド記述にバインドできます。 Advice.withCustomBindingsを使用してください。

実行時に定義されたフィールドを表現するには、fielddescription.latentを作成します。

関連する問題