2011-05-10 74 views
2

我想從運行時添加的Jar文件加載資源,但並沒有變得很遠。在運行時從Jar文件加載資源

這裏是我的代碼(常規):

URL url = new URL("jar:file:/out/resource.jar!/test.resource") 
def urlList = [] << url 
URL[] urls = urlList.toArray() 
URLClassLoader classLoader = new URLClassLoader(urls, this.class.getClassLoader()) 
InputStream stream = url.openStream() 

我得到這個錯誤: java.util.zip.ZipException:錯誤在java.util.zip.ZipFile.open打開zip文件 (本地方法)

問題:

1)我需要把 「test.resource」 在我的網址是什麼? 2)我的URLClassLoader和我的當前類的類加載器之間有什麼關係? 3)什麼是正確的方式來流這個資源(顯然我有什麼不工作)?

感謝

回答

0

如果jar文件在類路徑中已經那麼你就應該能夠做到Classloader.getResourceAsStream

是您當前classpath超出這個罐子?

+0

在我當前的classpath之外....在運行時添加。 – 2011-05-10 23:44:19

4

如果要將JAR文件添加到當前線程的ClassLoader中,您需要創建一個新的URLClassLoader,請使用當前類的ClassLoader作爲父項並添加新的JAR URL。您不得在您的網址中放入test.resource。不要忘記將新的ClassLoader分配給當前線程。看下面的例子:

URL url = new URL("file:/out/resource.jar") 
def urlList = [] << url 
URL[] urls = urlList.toArray() 
URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader) 
Thread.currentThread().setContextClassLoader(classLoader) 

現在,你應該能夠通過Thread.currentThread().getContextClassLoader().getResourceAsStream來獲取文件。

如果你真的只是想讀取JAR文件而不將它添加到你的classpath,你可以採取以下方法:

JarFile jar = new JarFile(new File('/out/resource.jar')) 
JarEntry jarEntry = jar.getJarEntry('test.resource') 

if(jarEntry) { 
    File file = new File(new URL("jar:file:/out/resource.jar!/test.resource").toURI()) 
} 
+0

「不要忘記將新ClassLoader分配到當前線程中」 - 如果你想訪問資源非常重要,如果你不喜歡它,那麼它就非常重要。感謝Ben,保存了一些問題 – Spedge 2013-10-17 10:43:43

0

我更熟悉Java比常規,但是這應該給你的InputStream你問:

JarFile jarFile = new JarFile(new File("/out/resource.jar")) 
JarEntry jarEntry = jarFile.getJarEntry("test.resource") 
InputStream inputStream = jarFile.getInputStream(jarEntry) 

沒有必要擔心的ClassLoader,除非:

  1. 呦你正試圖加載類(例如作爲插件),
  2. 你的資源都位於一些封裝結構中,或
  3. 你OSGi環境與多個不同的類路徑和類加載器中加載的資源(在這種情況下,你可以使用這樣的org.eclipse.core.runtime.FileLocator#resolve(URL)