[英]Make javagent use system classloader in Java < 9
我有一個依賴於一些依賴庫的 java-agent。 我們有一個自定義的類加載器,它不進行 globbing 並提供確定性的 class 加載,並通過-Djava.system.class.loader=
指定。 但是,似乎 java-agent 類仍在通過 AppClassLoader 加載,導致一些ClassNotFoundException
。 在這浪費了幾個小時之后,我遇到了這個JDK 錯誤,它概述了這個確切的問題,現在已經關閉,但只對 JDK 9+ 進行了修復。
我想知道 Java <=8 中是否有辦法強制指定的類加載器加載 java-agent 類。
自定義 class 加載程序看起來像這樣,
public class CustomClassloader extends URLClassLoader{
public CustomClassloader(ClassLoader parent) throws Exception {
//getJarPaths has the path of the java-agent jar as well as
//all dependency jar it needs.
super(getJarPaths(), parent);
}
private static URL[] getJarPaths() throws Exception {
//custom implementation
}
public void appendToClassPathForInstrumentation(String path) throws MalformedURLException {
assert(Thread.holdsLock(this));
super.addURL(Paths.get(path).toUri().toURL());
}
}
上面的類加載器與JDK9+完美配合,javaagent實際上是由自定義類加載器加載的。
JDK 8 和 JDK 9+ 的區別在於,JDK 8 在系統 class 路徑中添加了-javaagent
jar,而 JDK 9+ 則調用了自定義 ClassLoader 的appendToClassPathForInstrumentation
。
因此,在 JDK 8 中,如果您的自定義 ClassLoader 在嘗試查找 class 本身之前委托給父 ClassLoader(即系統 class 加載程序),則代理將由系統 ZA2F2ED4F8EBC2CBB4C21A29DC40ABC 加載。 為了解決這個問題,您的自定義 ClassLoader 可能會反轉委托順序:首先嘗試找到 class 本身,然后委托給父級。
例如,這可以通過重寫loadClass
方法來完成,如下所示:
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
synchronized (getClassLoadingLock(name)) {
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
c = findClass(name);
} catch (ClassNotFoundException e) {
c = super.loadClass(name, false);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
@Override
public URL getResource(String name) {
URL url = findResource(name);
if (url != null) {
return url;
}
return super.getResource(name);
}
@Override
public Enumeration<URL> getResources(String name) throws IOException {
List<URL> urls = Collections.list(findResources(name));
urls.addAll(Collections.list(getParent().getResources(name)));
return Collections.enumeration(urls);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.