java - 如何将一个类注入(inject)到java.lang包中

标签 java classloader instrumentation

当尝试通过 java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch 注入(inject) java.lang 命名空间中的类时在 OpenJDK 11 上,没有任何反应,也没有抛出任何错误。将类注入(inject)到不同的包中时,它按预期工作。

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 容器的问题。他们通常将对引导类加载器的委托(delegate)仅限于某些包。默认情况下,它显然总是包含 java.*,这就是为什么我想将我的 Dispatcher 类放在那里。我知道 org.osgi.framework.bootdelegation 但该属性仅在初始化期间读取。这意味着在运行时附加代理时,覆盖此值已经太晚了。

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

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

提供更多上下文:

我的想法是只将这个 Dispatcher 类注入(inject)引导类加载器。调度程序基本上只是持有一个静态 map 。代理的其余类将由专用的 URLClassLoader 加载,它是引导类加载器的子级。然后,代理将在调度程序的映射中注册 MethodHandle,以便注入(inject)的字节代码可以获取 MethodHandles,从而能够访问代理类加载器中加载的代理类。

最佳答案

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

Java 11 还删除了 sun.misc.Unsafe#defineClass 方法,但相同的方法在 jdk.internal.misc.Unsafe 中仍然可用。

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

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

有一个open ticket for adressing the need of Java agents to inject helper classes但在问题得到解决之前,这是一种常见的解决方法。

关于java - 如何将一个类注入(inject)到java.lang包中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57451427/

相关文章:

java - 使用 Hibernate 3.6.3 时获取 ClassNotFoundException 并且刚刚在 Tomcat 中添加了 DefaultPreUpdateEventListener

java - 从 GMAIL 应用程序和 Google MAIL 应用程序发送电子邮件时添加新行的不同行为

java - 从网页中获取文本的背景颜色

java - 接口(interface) com.sun.xml.ws.developer.WSBindingProvider 在类加载器中不可见

java - 禁用仪器库

java - 这个仪器如何完成

Java代理检测错误: Could not initialize class java. lang.invoke.CallSite

java - RxAndroid 链式操作

java - 如何将本地jar依赖添加到gradle中的另一个依赖中?

java - 使用 JarOutputStream 创建的 jar 的 URLClassLoader 问题