【发布时间】:2019-08-11 15:47:31
【问题描述】:
当尝试在 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 容器的问题。它们通常将对引导类加载器的委托限制为仅限于某些包。默认情况下,显然总是包含java.*,这就是为什么我想把我的Dispatcher 类放在那里。我知道org.osgi.framework.bootdelegation 但该属性仅在初始化期间被读取。这意味着在运行时附加代理时,覆盖该值已经太迟了。
另一种方法是检测所有已知的 OSGi 类加载器并将代理类列入白名单。但是对每个框架都这样做并针对每个版本进行测试似乎不太可行。
如何将java.lang.Dispatcher 之类的自定义类注入引导类加载器?是否有其他模式或最佳实践来避免 OSGi 引导委托问题?
提供更多上下文:
我的想法是只将这个Dispatcher 类注入到引导类加载器中。调度程序基本上只是持有一个静态地图。代理的其余类将由一个专用的 URLClassLoader 加载,该 URLClassLoader 是引导类加载器的子类。然后代理将在调度程序的 Map 中注册MethodHandles,以便注入的字节码可以获取 MethodHandles,从而可以访问代理类加载器中加载的代理类。
【问题讨论】:
标签: java classloader instrumentation