差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

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]
行 1: 行 1:
-{{tag>​java}} 
-====== Classloader Error: attempted duplicate class definition for name ====== 
-===== Problem ===== 
-在寫plugin相關程式時,會去override classloader做成自己想要的載入形式。而這陣子,偶爾會發生如以下Error:​ 
-<​code>​ 
-ava.lang.LinkageError:​ loader (instance of  org/​tonylin/​FunnyClassLoader):​ attempted ​ duplicate class definition for name: "​org/​apache/​commons/​cli/​BasicParser"​ 
-</​code>​ 
-而我們的實做是去extend java.net.URLClassLoader,其中關鍵程式碼如下:​ 
-<code java> 
-private Class<?>​ loadClass(String className) { 
- Class<?>​ clazz = findLoadedClass(className);​ 
- if (clazz != null) { 
- return clazz; 
- } 
- 
- // load locally 
- try { 
- clazz = findClass(className);​ 
- return clazz; 
- } catch (ClassNotFoundException e) { 
- // ignore 
- } 
- 
- // use the standard URLClassLoader (which follows normal parent 
- // delegation) 
- try { 
- return super.loadClass(className);​ 
- } catch (ClassNotFoundException e) { 
- return null; 
- } 
-} 
-</​code>​ 
-===== Solutions ===== 
-我寫了一個簡單的單元測試去trace這個問題,而內容為:​ 
-  * 新增一個jar檔到FunnyClassLoader的classpath中。 
-  * 產生5個thread去load某個jar檔中的class。 
-  * 驗證正確完成的工作數量為5。 
-<code java> 
-@Test 
-public void testConcurrentLoad() throws Exception{ 
- mClassLoader = new FunnyClassLoader(Thread.currentThread().getContextClassLoader());​ 
- mClassLoader.addURL(new File("​./​testdata/​commons-cli-1.2.jar"​));​ 
-  
- 
- List<​Thread>​ threads = new ArrayList<>​();​ 
- List<​String>​ passThread = new ArrayList<>​();​ 
- int size = 5; 
- CountDownLatch latch = new CountDownLatch(size);​ 
-  
- for( int i = 0 ; i < size ; i ++ ){ 
-  
- Thread t = new Thread(()->​{ 
- try { 
- mClassLoader.loadClass("​org.apache.commons.cli.BasicParser"​);​ 
- System.out.println("​pass:​ " + Thread.currentThread().getName());​ 
- passThread.add(Thread.currentThread().getName());​ 
- } catch (Exception e) { 
- e.printStackTrace();​ 
- } finally { 
- latch.countDown();​ 
- } 
- }); 
- threads.add(t);​ 
- } 
- threads.parallelStream().forEach(t->​t.start());​ 
-  
- latch.await();​ 
-  
- assertEquals(threads.size(),​ passThread.size());​ 
-} 
-</​code>​ 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~ 
-