繁体   English   中英

是否可以强制其他人的 java ClassLoader 加载包含有效 Java 类的字节码的外部字节数组?

[英]Is it possible to force someone else's java ClassLoader to load an external byte array containing the bytecode of a valid Java class?

我试图强制系统 java 类加载器(即ClassLoader.getSystemClassLoader() )加载由具有有效字节码的字节数组定义的外部类,以便随后由该类加载器加载的其他类可以知道并实例化外部类而无需获取一个NoClassDefFoundError

这肯定不起作用,因为它只在创建的类加载器上定义类,而不是在系统类加载器中:

URLClassLoader child = 
   new URLClassLoader(new URL[] { myJar.toURI().toURL()                          
   , ClassLoader.getSystemClassLoader());
Class.forName ("com.MyClass", true, child);

上面的代码将为子类加载器而不是系统类加载器定义com.MyClass

有什么方法可以实现吗?

您可以将反射与访问覆盖一起使用:

Method define = ClassLoader.class.getDeclaredMethod("defineClass",
                                      String.class, byte[].class, int.class, int.class);
define.setAccessible(true);
Class<?> clazz = (Class<?>)define.invoke(ClassLoader.getSystemClassLoader(),
                                      null, array, 0, array.length);

访问覆盖是必需的,因为我们正在调用一个protected方法,但作为一个protected方法,它仍然是 API 的一部分,它存在于所有实现中并且不会在未来版本中消失。


Java 9 引入了一种惊人的简单方法来实现相同的目标,而无需 hack,只要您自己的类也已通过应用程序类加载器加载(这是默认设置):

Class<?> clazz = MethodHandles.lookup().defineClass(array);

这只是在与包含此语句的类相同的类加载上下文中创建类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM