如何在运行时使用 Java 调试接口从 Jar 文件加载 class

How to load a class from a Jar file at runtime with the Java Debug Interface

我试图在运行时注入一个 ByteBuddy 代理,以防在启动 JVM 时 ByteBuddy 不在机器上(因此不在 class 路径中)。我的第一个想法是将 bytebuddy 库 jar 文件添加到 class 路径中的目录中,以便在我注入代理时加载它,但我找不到检索 class 路径的方法运行 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是我自己的方法,分别得到一个ReferenceType和一个Method对象。 遗憾的是,由于 java.net.URL[] class 未加载到 JVM 中,因此我无法获得更多信息,因此我无法为其获取 ReferenceType。

我该如何追求我的追求?

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