【问题标题】:How to load a class from a Jar file at runtime with the Java Debug Interface如何在运行时使用 Java 调试接口从 Jar 文件加载类
【发布时间】:2021-12-29 14:29:08
【问题描述】:

我试图在运行时注入一个 ByteBuddy 代理,以防 JVM 启动时机器上不存在 ByteBuddy(因此不在类路径中)。我的第一个想法是将 bytebuddy 库 jar 文件添加到类路径中存在的目录中,以便在注入代理时加载它,但是我找不到检索正在运行的 JVM 的类路径的方法。因此,我想知道是否可以在注入代理之前使用 Java 调试接口在 JVM 中手动加载 bytebuddy 库 jar 文件。

我尝试修改 this 代码(使用 JDI),它将前两行转换为:

ClassType jarFileClass = (ClassType) findClassRef("java.util.jar.JarFile");
Method jarFileInit = findOverloadRef("java.util.jar.JarFile", "<init>", "java.lang.String");
Method entries = findOverloadRef("java.util.jar.JarFile", "entries", "");
ArrayList<Value> argz = new ArrayList<Value>();
argz.add(vm.mirrorOf(path)); // path is the path to the bytebuddy library jar file, as a String
ObjectReference jarFile = jarFileClass.newInstance(ev.thread(), jarFileInit, argz, ObjectReference.INVOKE_SINGLE_THREADED);
ObjectReference x = jarFile.invokeMethod(ev.thread(), entries, new ArrayList<Value>(), ObjectReference.INVOKE_SINGLE_THREADED);

其中findClassReffindOverloadRef 是我自己的方法,分别获取ReferenceTypeMethod 对象。 可悲的是,由于java.net.URL[] 类未加载到 JVM 中,因此我无法获得任何进一步的信息,因此我无法获得它的 ReferenceType。

我怎样才能追求我的追求?

【问题讨论】:

  • 使用 Attach API 将代理加载到已运行的 VM 中。如果您的代理已在 VM 中运行,请使用 Instrumentation.appendToSystemClassLoaderSearch
  • 在 JVM 中没有加载库 jar 的情况下,ByteBuddy 代理会运行吗?
  • 然后将代理和所有需要的依赖打包到一个jar中。
  • 我去试试,谢谢!

标签: java byte-buddy javaagents jdi


【解决方案1】:

通常,代理会将其所有依赖项隐藏到一个 jar 中。这仍然可能是有问题的。 Byte Buddy 是一个相当常见的依赖项,它已经在类路径上,但在不同的版本中。为了避免这种情况,许多代理将它们的依赖关系隐藏到不同的命名空间中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-18
    • 2012-06-16
    • 2023-03-10
    • 2014-07-30
    • 2011-11-26
    • 2012-10-20
    • 2017-04-30
    • 2010-12-18
    相关资源
    最近更新 更多