Загрузить ресурс, содержащийся в банке - PullRequest
21 голосов
/ 22 февраля 2009

В моем приложении я загружаю ресурсы следующим образом:

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

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

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

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

java -jar app.jar

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

jar:/root/app.jar!/repository

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

Я буду использовать имя dir-репозитория для создания этого:

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

Таким же образом я получу одно имя файла (вместо dir) и буду использовать его следующим образом:

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

Ответы [ 3 ]

35 голосов
/ 22 февраля 2009

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

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

РЕДАКТИРОВАТЬ: увидев ваш обновленный ответ, кажется, что другие фрагменты кода полагаются на данные, находящиеся в одном физическом файле в файловой системе. Поэтому ответ заключается не в том, чтобы связать его в файл jar. Вы могли бы проверить, находится ли он в отдельном файле, а если нет, извлечь его во временный файл, но это довольно хакерская IMO.

9 голосов
/ 08 декабря 2012

При запуске кода с использованием 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 с некоторой осторожностью, чтобы справиться с различиями между Windows и 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 в исходном коде Diffusive, который можно найти на SourceForge по адресу github.com/robphilipp/diffusive

.

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

5 голосов
/ 22 февраля 2009

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

...