【问题标题】:Specify class loader for loading dependencies of an advice's dependency指定类加载器以加载通知依赖项的依赖项
【发布时间】:2020-12-22 07:10:56
【问题描述】:

我有一个建议类,它使用代理 jar 中的另一个类,但是这个其他类依赖于代理 jar 中不存在的类。代理 jar 中不存在的此类存在于应用程序类加载器上的另一个 jar 中。代理 jar 在系统类加载器上。所以我遇到了 NoClassDefFoundError。我已尝试按照this other post 中的建议使用 Transformer.ForAdvice,但这仅适用于建议类。

// In agent jar on system class loader
MyAdviceClass {
  @Advice.OnMethodEnter
  public static void onMethodEnter() {
    YetAnotherClass.doSomething(); // works fine as Transformer.ForAdvice makes use of the correct class loader while inlining this code
    AnotherClass.doSomething(); // NoClassDefFoundError happens inside this method call
  }
}

// In agent jar on system class loader
public class AnotherClass {
  public static void doSomething() {
    YetAnotherClass.doSomething();  // NoClassDefFoundError happens here because the system class loader is used to load YetAnotherClass, but that class is only present on the application class loader
  }
}

// In user jar on application class loader
public class YetAnotherClass {
  public static void doSomething() {
    // do something else
  }
}

变换如下所示:

.transform(new AgentBuilder.Transformer
                           .ForAdvice()
                           .include(getClass().getClassLoader())
                           .advice(methodMatcher, "com.something.advice.MyAdvice.class"));

代理 jar 中存在 MyAdviceClass 和 AnotherClass。 YetAnotherClass 存在于用户 jar 中,它不在系统类加载器上,它在应用程序类加载器上。我怎么解决这个问题?即有没有一种方法可以强制在 AnotherClass 中使用应用程序类加载器?

【问题讨论】:

    标签: byte-buddy


    【解决方案1】:

    我假设从被检测的类中看不到 AnotherClass。在这种情况下,您不应将该类包含在 ypur 代理 jar 中,而是将其放在一个单独的 jar 中,您可以通过 Instrumentation.appendToBootSearchPath 将其附加到引导加载程序。引导加载程序上的类是普遍可见的,因此您的检测类应该可以访问。

    如果注入的类引用了检测类加载器的类,您可能需要使用 ClassInjector 将类注入到类加载器中。

    【讨论】:

    • 谢谢。您关于从检测类中看不到 AnotherClass 的假设是正确的。但这不是问题。 AnotherClass 和 YetAnotherClass 都可以从插桩类的内联通知代码中看到。但是 YetAnotherClass 从 AnotherClass 内部不可见,并导致 NoClassDefFoundError。看来我需要将 YetAnotherClass 注入系统类加载器。
    猜你喜欢
    • 1970-01-01
    • 2020-07-17
    • 2012-10-30
    • 2016-08-17
    • 2017-12-03
    • 1970-01-01
    • 2020-07-05
    • 2010-09-15
    • 2021-06-11
    相关资源
    最近更新 更多