繁体   English   中英

如何将类注入java.lang包中

[英]How to inject a class into the java.lang package

当尝试通过OpenJDK 11上的java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch注入java.lang命名空间中的类时,没有任何反应并且不会引发错误。 将类放入注入不同的包时,它按预期工作。

JarFile jar = new JarFile(new File("file/to/bootstrap.jar));
instrumentation.appendToBootstrapClassLoaderSearch(jar);
// throws ClassNotFoundException java/lang/Dispatcher
Class.forName("java.lang.Dispatcher", false, null);
bootstrap.jar
 └─ java/lang/Dispatcher.class

我想这样做的原因是为了克服一些OSGi容器的问题。 它们通常将对bootstrap类加载器的委派限制为仅限于某些包。 默认情况下,显然总是包含java.*这就是为什么我想把Dispatcher类放在那里。 我知道org.osgi.framework.bootdelegation但该属性仅在初始化期间被读取。 这意味着在运行时附加代理时,覆盖此值已经太晚了。

另一种方法是检测所有已知的OSGi类加载器并将代理类列入白名单。 但是为每个框架执行此操作并测试每个版本似乎不太可行。

如何将自定义类(如java.lang.Dispatcher注入引导类加载器? 是否有其他模式或最佳实践来避免OSGi bootdelegation问题?

提供更多背景信息:

我的想法是只将这个Dispatcher类注入bootstrap类加载器。 调度程序基本上只包含一个静态Map。 代理程序的其余类将由专用的URLClassLoader加载,该类是引导类加载器的子代。 然后代理将在调度程序的Map中注册MethodHandle ,以便注入的字节代码可以获得MethodHandles,它允许访问代理程序类加载器中加载的代理程序的类。

可以使用不安全的API。 从Java 9开始,引导类加载器的实现已更改为仅检查已指定包的指定jmod,但不再检查引导搜索路径。

Java的11也去掉了sun.misc.Unsafe#defineClass方法,但同样的方法仍然可用在jdk.internal.misc.Unsafe

你必须打开该类的内部模块。 您可以使用sun.misc.Unsafe执行此操作,它允许您编写字段值( accessible )而无需可访问性检查或使用Instrumentation的官方API。

如果您正在使用Byte Buddy,请查看为所有方法提供实现的ClassInjector实现。

有一个开放的票据可以解释Java代理注入帮助程序类的需要,但在解决之前,这是一个常见的解决方法。

暂无
暂无

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

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