是否可以强制其他人的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?

查看:206
本文介绍了是否可以强制其他人的Java ClassLoader加载包含有效Java类的字节码的外部字节数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图强制System java类加载器(即 ClassLoader.getSystemClassLoader())加载由具有有效字节码的字节数组定义的外部类,以便其他此类加载器随后加载的类可以知道并实例化外部类,而不会出现 NoClassDefFoundError

I'm trying to force the System java classloader (i.e. ClassLoader.getSystemClassLoader()) to load an external class defined by a byte array with valid bytecode so that other classes subsequently loaded by this classloader can know about and instantiate the external class without getting a NoClassDefFoundError.

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

This surely does not work as it only defines the class on the classloader created, not in the System classloader:

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

上面的代码将定义 com.MyClass

有什么方法可以实现?

推荐答案

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

You can use Reflection with access override:

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 方法,但作为 protected 方法,它仍然是API的一部分,它存在于所有实现中,不会

The access override is needed because we’re invoking a protected method, but being a protected method, it’s still part of the API, which exists in all implementations and won’t go away in future versions.

Java 9引入了一种惊人的简单方法,无需破解即可您自己的类也已通过应用程序类加载器加载(默认设置):

Java 9 introduced an astonishing simple way to achieve the same without a hack, as long as your own class has been loaded through the application class loader as well (as is the default):

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

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

This simply creates the class within the same class loading context as the class containing this statement.

这篇关于是否可以强制其他人的Java ClassLoader加载包含有效Java类的字节码的外部字节数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆