簡體   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