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

标签 java classloader

我试图强制系统 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);

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


Java 9 引入了一种非常简单的方法来实现同样的效果,无需破解,只要您自己的类也已通过应用程序类加载器加载(默认情况下):

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

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

关于java - 是否可以强制其他人的 java ClassLoader 加载包含有效 Java 类字节码的外部字节数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48691773/

相关文章:

java - AsyncTask在doInBackground中止

java - java谜语 undefined variable

java - Jersey 安全和 session 管理

java - 以编程方式加载不同的 .class 文件运行 JUnit 测试

java - 如何从 JarClassLoader 和 Applet Launcher 调用返回字符串数据的 applet 方法

Tomcat 错误 - Grails 应用程序 - NoClassDefFoundError

java动态选择要执行的类

java - 在 Android 上使用 KSOAP2 发送 SOAP 消息

java - getResource 还不起作用 getResourceAsStream 可以

java - 使用java修剪json对象中的冗余属性