差異處
這裏顯示兩個版本的差異處。
Both sides previous revision 前次修改 下次修改 | 前次修改 | ||
java:basic:classloader:duplicate_class_def_error [2016/12/15 13:51] tony |
java:basic:classloader:duplicate_class_def_error [2023/06/25 09:48] (目前版本) |
||
---|---|---|---|
行 8: | 行 8: | ||
而我們的實做是去extend java.net.URLClassLoader,其中關鍵程式碼如下: | 而我們的實做是去extend java.net.URLClassLoader,其中關鍵程式碼如下: | ||
<code java> | <code java> | ||
- | private Class<?> loadClass(String className) { | + | public Class<?> loadClass(String className) throws ClassNotFoundException { |
Class<?> clazz = findLoadedClass(className); | Class<?> clazz = findLoadedClass(className); | ||
if (clazz != null) { | if (clazz != null) { | ||
行 31: | 行 31: | ||
} | } | ||
</code> | </code> | ||
+ | 目的是為了先讀取已載入的class,若尚未載入則優先搜尋classpath中是否有此class,最後才去找parent。 | ||
===== Solutions ===== | ===== Solutions ===== | ||
我寫了一個簡單的單元測試去trace這個問題,而內容為: | 我寫了一個簡單的單元測試去trace這個問題,而內容為: | ||
行 68: | 行 69: | ||
assertEquals(threads.size(), passThread.size()); | assertEquals(threads.size(), passThread.size()); | ||
+ | } | ||
+ | </code> | ||
+ | 最後發現問題是由於: 當兩個thread同時存取loadclass時,若class已被define過,就會產生此錯誤。最後寫法是: | ||
+ | <code java> | ||
+ | @Override | ||
+ | public Class<?> loadClass(String className) throws ClassNotFoundException { | ||
+ | synchronized (getClassLoadingLock(className)) { | ||
+ | // original code | ||
+ | } | ||
} | } | ||
</code> | </code> |