загрузить ресурс из файла JAR во время выполнения - PullRequest
2 голосов
/ 11 мая 2011

Я пытаюсь загрузить ресурс из файла 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: ошибка при открытии zip-файла at java.util.zip.ZipFile.open (собственный метод)

Вопросы:

1) мне нужно поместить "test.resource" в мой URL? 2) Какая связь между моим URLClassLoader и загрузчиком классов моего текущего класса? 3) Каков правильный способ для потоковой передачи в этом ресурсе (очевидно, что у меня не работает)?

Спасибо

Ответы [ 3 ]

4 голосов
/ 11 мая 2011

Если вы хотите добавить JAR-файл в ClassLoader вашего текущего потока, вы создадите новый URLClassLoader, используйте ClassLoader текущего класса в качестве родительского и добавьте новые URL-адреса JAR. Вы не можете указывать test.resource в своем URL. Не забудьте назначить новый 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, не добавляя его в путь к классам, вы можете воспользоваться следующим подходом:

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 голосов
/ 07 мая 2013

Я больше знаком с Java, чем с Groovy, но это должно дать вам 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 с несколькими различными ClassPaths и ClassLoaders (в этом случае вы можете использовать что-то вроде org.eclipse.core.runtime.FileLocator#resolve(URL))
0 голосов
/ 11 мая 2011

Если файл jar уже находится в вашем classpath, тогда вы просто должны сделать: Classloader.getResourceAsStream

Это банка за пределами вашего текущего пути к классам?

...