[英]How to load a Java class from the classpath *as a byte array* for bytecode injection?
[英]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.