簡體   English   中英

ByteBuddy 1.10.2 拋出 `java.lang.IllegalStateException:無法解析 java.lang.Exception` 的類型描述,以及類似的

[英]ByteBuddy 1.10.2 throws `java.lang.IllegalStateException: Cannot resolve type description for java.lang.Exception`, and similar

在為Instrumentation安裝AgentBuilder轉換時,我看到Cannot resolve type description來自AgentBuilder.Listener.onError(...) Cannot resolve type description錯誤。

代理代碼為:

  public static void premain(final String agentArgs, final Instrumentation inst) {
    System.out.println("from bytebuddy: agent premain");
    new AgentBuilder.Default(new ByteBuddy().with(TypeValidation.DISABLED))
      .disableClassFormatChanges()
      .ignore(none())
      .with(RedefinitionStrategy.RETRANSFORMATION)
      .with(InitializationStrategy.NoOp.INSTANCE)
      .with(TypeStrategy.Default.REDEFINE)
      .with(new AgentBuilder.Listener() {
        public void onDiscovery(final String typeName, final ClassLoader classLoader, final JavaModule module, final boolean loaded) {
          log("Event::onDiscovery(" + typeName + ", " + getNameId(classLoader) + ", " + module + ", " + loaded + ")");
        }

        public void onTransformation(final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module, final boolean loaded, final DynamicType dynamicType) {
          log("Event::onTransformation(" + typeDescription.getName() + ", " + getNameId(classLoader) + ", " + module + ", " + loaded + ", " + dynamicType + ")");
        }

        public void onIgnored(final TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module, final boolean loaded) {
          log("Event::onIgnored(" + typeDescription.getName() + ", " + getNameId(classLoader) + ", " + module + ", " + loaded + ")");
        }

        public void onError(final String typeName, final ClassLoader classLoader, final JavaModule module, final boolean loaded, final Throwable throwable) {
          log("Event::onError(" + typeName + ", " + getNameId(classLoader) + ", " + module + ", " + loaded + ")", throwable);
        }

        public void onComplete(final String typeName, final ClassLoader classLoader, final JavaModule module, final boolean loaded) {
          log("Event::onComplete(" + typeName + ", " + getNameId(classLoader) + ", " + module + ", " + loaded + ")");
        }
      })
      .type(hasSuperType(named("com.ning.http.client.AsyncHttpClientConfig$Builder")))
      .transform(new Transformer() {
        public DynamicType.Builder<?> transform(final DynamicType.Builder<?> builder, final     
          System.out.println("from bytebuddy: transform");
          TypeDescription typeDescription, final ClassLoader classLoader, final JavaModule module) {
          return builder.visit(Advice.to(AHCBuilderExit.class).on(isDefaultConstructor()));
        }})
      .installOn(inst);
  }

這是使用 ByteBuddy v1.10.2 和 Mule 4 (jdk1.8) 作為目標應用程序。

有關於這個同樣的問題類似的帖子在這里,但反應還沒有導致我的解決方案。

輸出顯示“來自 bytebuddy:agent premain”,但沒有顯示“來自 bytebuddy:transform”。 相反,日志顯示屬於引導類加載器的許多類的異常,例如:

Event::onError(org.mule.weave.v2.el.WeaveExpressionLanguage, org.mule.runtime.module.artifact.api.classloader.MuleArtifactClassLoader@6d4b1d14, null, false)
java.lang.IllegalStateException: Cannot resolve type description for java.lang.Exception
    at net.bytebuddy.pool.TypePool$Resolution$Illegal.resolve(TypePool.java:159)
    at net.bytebuddy.pool.TypePool$Default$WithLazyResolution$LazyTypeDescription.delegate(TypePool.java:914)
    at net.bytebuddy.description.type.TypeDescription$AbstractBase$OfSimpleType$WithDelegation.getSuperClass(TypeDescription.java:8031)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.getSuperClass(TypeDescription.java:3619)
    at net.bytebuddy.description.type.TypeDefinition$SuperClassIterator.next(TypeDefinition.java:314)
    at net.bytebuddy.description.type.TypeDefinition$SuperClassIterator.next(TypeDefinition.java:281)
    at net.bytebuddy.matcher.HasSuperTypeMatcher.matches(HasSuperTypeMatcher.java:53)
...

似乎正在查詢類型描述的類加載器沒有提供所需的類。 有沒有辦法為這些查找指定備用ClassFileLocator

導致錯誤的特定類加載器是: org.mule.runtime.module.artifact.api.classloader.MuleArtifactClassLoader

有趣的是,當使用 Byteman 作為代理時,此檢測按預期工作,具有以下規則文件:

RULE AsyncHttpClientConfig.Builder.<init>
CLASS com.ning.http.client.AsyncHttpClientConfig$Builder
METHOD <init>
AT EXIT
IF TRUE
DO
  traceln("from byteman: AsyncHttpClientConfig$Builder.<init> triggered: " + getClass().getClassLoader());
ENDRULE

任何意見,將不勝感激! 感謝您的幫助!

堆棧跟蹤顯示您正在使用 Byte Buddy 應用您未與 Byteman 一起使用的超類型檢查。 如果您代替您hasSuperType(named(...))匹配只有named(...)它可能沒有錯誤工作,因為這是錯誤似乎發生。 Byte Buddy 需要解析類層次結構中的所有類才能應用這個匹配器,這在您的情況下似乎是不可能的。

然而, ClassLoader無法解析java.lang.Exception的類文件似乎很奇怪; 您正在使用的類加載器可能是一個自定義實現,它不會委托給引導加載器。

您可以通過在您的代理中定義一個自定義的LocationStrategy來避免這種情況,該策略始終將引導加載程序作為替代選項進行查詢:

class BootFallbackLocationStrategy implements AgentBuilder.LocationStrategy {

  @Override
  public ClassFileLocator classFileLocator(ClassLoader classLoader, JavaModule module) {
     return new ClassFileLocator.Compound(
       ClassFileLocator.ForClassLoader.of(classLoader),  
       ClassFileLocator.ForClassLoader.ofBootLoader())
  }
}

正如我的評論中提到的,如果您可以命名無法解析類文件的類加載器的類型,我可能會提供更詳細的答案。

我將在 Byte Buddy 的未來版本中添加此類位置策略的標准實現,以便更輕松地解決此問題。 在這張票中跟蹤進度: https : //github.com/raphw/byte-buddy/issues/794

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM