开发者

load resource from Jar file at runtime

I am trying to load a resource from a Jar file added in at runtime and not getting very far.

Here is my code (groovy):

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

I get this error: java.util.zip.ZipException: error in opening zip file at java.util.zip.ZipFile.open(Native Method)

Questions:

1) do I need to put "test.resource" in my url? 2) What is the relationship between my URLClassLoader and my current class's classloader? 3) what is the proper way to stream in this resource (obviously what I have doesn't work)?

Thanks


If you want to add a JAR file to your current thread's ClassLoader you'd create a new URLClassLoader, use the current class's ClassLoader as parent and add the new JAR URLs. You may not put test.resource in your URL. Don't forget to assign the new ClassLoader to your current thread. See the example below:

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)

Now you should be able to get the file via Thread.currentThread().getContextClassLoader().getResourceAsStream.

If you actually just want to read the file from a JAR without adding it to your classpath you can take the following approach:

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())
}


If the jar file is in your classpath already then you should just be able to do Classloader.getResourceAsStream

Is this jar outside your current classpath?


I'm more familiar with java than groovy, but this should give you the InputStream you asked for:

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

No need to worry about ClassLoader unless:

  1. You are trying to load classes (e.g. as plugins),
  2. Your resources are located within some package structure, or
  3. You are loading resources within an OSGi environment with multiple distinct ClassPaths and ClassLoaders (in which case you might use something like org.eclipse.core.runtime.FileLocator#resolve(URL))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜