2011-07-10 22 views

回答

37

它是由在其中的資源(即通常jar文件)使用-classpath選項指定的順序指定。類路徑中'較早'的資源優先於後面指定的資源。這也可以在應用程序的清單文件中設置,然後您不需要提供-classpath選項。您可能需要檢查these articles關於如何使用清單文件。

的「類是如何發現」的詳盡的描述可以發現here,其中上JAR類路徑類的部分描述的JAR-文件搜索的邏輯。

+0

如果我使用Maven,這是否意味着它是事實上的隨機的?在測試時設置classpath(MANTIME.MF中的類路徑不起作用)(jar從本地回購中獲取) –

+0

由於Maven 2.0.9,可以像這裏描述的那樣進行處理(http://stackoverflow.com/questions/793054/) Maven的classpath中階的問題)。 – mouser

+1

任何官方文件,確認'資源「早」在classpath中優先於,是經過them.'指定的資源? –

7

ClassLoader確定其中資源將位於(由ClassLoader的JavaDoc的拍攝):

ClassLoader類使用委託模型來搜索類和資源。每個ClassLoader實例都有一個關聯的父類加載器。當要求找到一個類或資源,一個ClassLoader的實例將委託的類或資源於它的父類加載器搜索試圖找到類或資源本身之前。虛擬機內置的類加載器稱爲「引導類加載器」,它本身沒有父類,但可以作爲ClassLoader實例的父類。

因此,無論在你的代碼類的getResource#或#類的getResourceAsStream被調用,發生這種情況(從Class.java拍攝)

public java.net.URL getResource(String name) { 
    name = resolveName(name); 
    ClassLoader cl = getClassLoader0(); 
    if (cl==null) { 
     // A system class. 
     return ClassLoader.getSystemResource(name); 
    } 
    return cl.getResource(name); 
} 

ClassLoader.java:

public URL getResource(String name) { 
    URL url; 
    if (parent != null) { 
     url = parent.getResource(name); 
    } else { 
     url = getBootstrapResource(name); 
    } 
    if (url == null) { 
     url = findResource(name); 
    } 
    return url; 
} 

其中的ClassLoader實際上#findResource將被ClassLoader實現覆蓋。這意味着行爲是在應用服務器上的不同,一個Tomcat或者如果你是從一個jar文件運行時,它依賴於環境的類加載器實現您目前英寸

Here是一個例子,你可以使用跟蹤你的具體情況下發生了什麼。

+0

確實,它是依賴於類加載器的,但是因爲我正在使用Java SE和標準類加載器,所以另一個答案適用。 –

+1

這應該添加使用通常的URLClassLoader時發生的情況,並使用多個jar /目錄。 –