Загрузите ресурс, содержащийся в банке
В моем приложении я загружаю ресурсы таким образом:
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);
Таким же образом я получу одно имя файла (вместо dir), и я буду использовать его следующим образом:
System.setProperty("javax.net.ssl.trustStore", fileNameString)
Ответы
Ответ 1
Похоже, что вы пытаетесь загрузить ресурс с помощью FileInputStream
или что-то в этом роде. Не делайте этого: вместо вызова getResource
вызовите getResourceAsStream
и прочитайте данные из этого.
(Вместо этого вы можете загружать ресурсы из URL-адреса, но вызов getResourceAsStream
немного удобнее.)
EDIT: увидев ваш обновленный ответ, кажется, что другие биты кода зависят от данных, находящихся в физическом одиночном файле в файловой системе. Поэтому ответ заключается не в том, чтобы связать его в файле jar в первую очередь. Вы можете проверить, есть ли это в отдельном файле, а если не извлекать его во временный файл, но это довольно хакерская ИМО.
Ответ 2
При запуске кода с использованием 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/диффузионное
И метод создания URL для Windows и Unix/Linux/MacOSX из относительных и абсолютных путей в RestfulDiffuserManagerResource.createJarClassPath(...)
Ответ 3
Построить a URL
, вы можете загрузить ресурс (даже в файле jar) с помощью метода openStream
.