Загрузите ресурс, содержащийся в банке


21

В моем приложении я загрузить ресурсы таким образом:

WinProcessor.class.getResource("repository").toString(); 

, и это дает мне:

file:/root/app/repository (and I replace "file:" with empty string) 

Это прекрасно работает, когда я запускаю мое приложение с IDE , но когда я запускаю банку моего приложения:

java -jar app.jar 

путь становится:

jar:/root/app.jar!/repository 

есть ли способ решить эту проблему?

Я буду использовать «хранилище» имя реж для того, чтобы создать это:

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null); 

таким же образом, я получу одно имя файла (вместо директории), и я буду использовать это так:

System.setProperty("javax.net.ssl.trustStore", fileNameString) 
35

Похоже, что вы пытаетесь загрузить ресурс, используя FileInputStream или что-то в этом роде. Не делайте этого: вместо вызова getResource вызовите getResourceAsStream и прочитайте данные с этого.

(Вы можете загрузить ресурсы из URL вместо этого, но называть getResourceAsStream немного более удобным.)

EDIT: Увидев обновленный ответ, кажется, другие биты кода полагаются на том, что данные в физический отдельный файл в файловой системе. Поэтому ответ заключается не в том, чтобы связать его в файле jar в первую очередь. You может проверить, находится ли он в отдельном файле, а если не извлекать его во временный файл, но это довольно хакерский IMO.

+1

Согласитесь. Всякий раз, когда вы не можете сказать со 100% уверенностью, что будете иметь дело с физическими отдельными файлами (java web start для одного), вы всегда должны кодировать потоки. 22 фев. 092009-02-22 12:16:38


5

Построить URL, вы можете загрузить ресурс (даже в файле JAR), используя метод openStream.

+1

Это то, что делает 'getResourceAsStream'. 12 июл. 162016-07-12 14:20:56


9

При запуске кода с использованием java -jar app.jar, java использует ТОЛЬКО путь класса, определенный в манифесте JAR-файла (то есть Class-Path). Если класс находится в app.jar, или класс находится в пути класса, установленном в атрибуте Class-Path манифеста JAR, вы можете загрузить этот класс, используя следующий фрагмент кода, где className - это полное имя класса.

final String classAsPath = className.replace('.', '/') + ".class"; 
final InputStream input = ClassLoader.getSystemResourceAsStream(path/to/class); 

Теперь, если класс не является частью JAR, и это не в манифесте-х Class-Path, то загрузчик классов не найдет. Вместо этого вы можете использовать URLClassLoader с некоторой осторожностью в отношении различий между окнами и Unix/Linux/MacOSX.

// the class to load 
final String classAsPath = className.replace('.', '/') + ".class"; 

// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below) 
final URL url = new URL("file", null, "///C:/Users/diffusive/app.jar"); 
//final URL url = new URL("file", null, "/Users/diffusive/app.jar"); 

// create the class loader with the JAR file 
final URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url }); 

// grab the resource, through, this time from the `URLClassLoader` object 
// rather than from the `ClassLoader` class 
final InputStream input = urlClassLoader.getResourceAsStream(classAsPath); 

В обоих примерах вы должны будете иметь дело с исключениями, а также тот факт, что входной поток null, если ресурс не может быть найден. Кроме того, если вам нужно получить InputStream в byte[], вы можете использовать общие для Apache IOUtils.toByteArray(...). И, если вы тогда захотите Class, вы можете использовать метод загрузчика класса defineClass(...), который принимает byte[].

Вы можете найти этот код в ClassLoaderUtils класса в диффузионной исходный код, который вы можете найти на SourceForge в github.com/robphilipp/diffusive

и способ создания URL для Windows, и Unix/Linux/MacOSX от относительных и абсолютных путей в RestfulDiffuserManagerResource.createJarClassPath(...)