我們的Java應用程序依賴於網絡共享上可用的一些資源。此網絡共享位於類路徑中,並且在運行時使用MyClass.class.getResourceAsStream("/myfile.jpg")
讀取資源。如何從java classpath中的網絡目錄正確加載資源?
java -Djava.class.path=\\myserver\myshare:C:\myjar.jar MainClass
當共享在啓動時可用時,一切都運行順利。位於共享中的圖像和屬性文件可以使用getResourceAsStream()
來讀取。但是,如果股票不在線應用程序啓動時,即使份額聯機讀取之前的任何資源,它們不能使用getResourceAsStream()
讀取。
否則使用eclispse +反編譯一些挖,我注意到一個區別。默認類加載器繼承自URLClassLoader,其成員(URLClassPath
)包含URLClassPath.Loader
實例的列表。在第一種情況下,它包含URLClassPath.FileLoader
和URLClassPath.JarLoader
。在第二種情況下,它只包含一個jar加載器。
這就像Java的確定類路徑條目是無效的,並完全放棄它。
這是爲什麼?我怎樣才能避免它?
更新 我無法改變,使我們加載的,因爲幾個原因資源的機制:
- 有目前加載文件這樣對我的改變有太多的領域此刻
- 在有些情況下由資源實際上是由一個第三方組件
裝我沒有問題,創建自定義的類裝載器的情況下,我只需要一些指導如何做到這一點。
我想這個問題,但未能獲得預期的結果:
import java.net.URL;
import java.net.URLClassLoader;
public class MyUrlClassLoader extends URLClassLoader {
public MyUrlClassLoader(ClassLoader parent) {
super(new URL[0], parent);
System.out.println("MyUrlClassLoader ctor");
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
System.out.println("url find class " + name);
return super.findClass(name);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
System.out.println("url load class " + name);
return super.loadClass(name);
}
@Override
public URL getResource(String name) {
System.out.println("url get resource " + name);
return super.getResource(name);
}
}
import java.net.URL;
public class ClassLoaderMain {
public static void main(String[] args) throws ClassNotFoundException {
URL url = ClassLoaderMain.class.getResource("/myfile.txt");
System.out.print("Loaded? ");
System.out.println(url != null);
System.out.println(ClassLoaderMain.class.getClassLoader().toString());
System.out.println(MyUrlClassLoader.class.getClassLoader().toString());
System.out.println(FakeClass.class.getClassLoader().toString());
}
}
當我運行java -cp . -Djava.system.class.loader=MyUrlClassLoader ClassLoaderMain
此輸出:
MyUrlClassLoader ctor
url load class java.lang.System
url load class java.nio.charset.Charset
url load class java.lang.String
url load class ClassLoaderMain
Loaded? true
[email protected]
[email protected]
[email protected]
所以正在創建我的類加載器,並且正在調用load類,但它似乎不是它正在加載的類的類加載器?
最安全的辦法大概是寫自己的類加載器。這意味着你完全控制。 – biziclop
我會如何去做這個簡單的情況?到目前爲止,我所見過的所有資源似乎都在運行時用於按名稱加載類(例如,Class.forName(「string」))。我寧願不必每次調用'getResourceAsStream()'手動創建一個新的類加載器並調用它。 – Travis
爲什麼不能使用File和FileInputStream來訪問文件? – pauli