Как загрузить ресурс из встроенного файла JAR

#java #jboss #jar #classloader

#java #jboss #jar #classloader

Вопрос:

Я пытаюсь загрузить ресурс, который содержится во встроенном файле JAR. Проект фактически развернут в JBoss с использованием файла EAR со следующей структурой:

 deploy.ear
|
|-> project.sar
    |
    |-> sub_project.jar
    |   |
    |   |-> settings.xml
    |
    |-> com/path/project/
        |
        |-> main.class
  

От main.java я хотел бы получить InputStream for settings.xml . Каков правильный способ сделать это?

Насколько я понимаю, следующий код должен работать, но он возвращает null :

 this.getClass().getResourceAsStream("settings.xml");
  

Обновить

После некоторых проб и ошибок работают следующие инструкции:

 getClass().getResourceAsStream("/settings.xml");
getClass().getResourceAsStream("/sub_project.jar/settings.xml");
getClass().getClassLoader().getResourceAsStream("/settings.xml");
getClass().getClassLoader().getResourceAsStream("settings.xml");
getClass().getClassLoader().getResourceAsStream("sub_project.jar/settings.xml");
getClass().getClassLoader().getResourceAsStream("/sub_project.jar/settings.xml");
  

Комментарии:

1. загрузчик классов Java не может загружать ресурсы из встроенных файлов jar, поэтому ваша настройка не будет работать. Решение one jar решает эту проблему, см. Ответ Эрана.

2. Не уверен, что /sub_project.jar/settings.xml это стандартная нотация. Может быть расширением JBoss.

3. Я был удивлен, почему «settings.xml «сбой, пока»/settings.xml » сработало, но затем я прочитал документацию: если имя ресурса начинается с «/», оно остается неизменным; в противном случае имя пакета добавляется к имени ресурса после преобразования «.» в «/». Class.class делает это, но ClassLoader.class не работает. Сегодня узнал кое-что новое…

Ответ №1:

Это может быть хорошим ресурсом: http://one-jar.sourceforge.net/version-0.95 /

Основная идея заключается в том, что внутренний JAR не загружается загрузчиком классов, который автоматически загрузил внешний JAR, вам нужно сделать это вручную, например, с помощью StreamClassLoader для загрузки внутреннего jar

Только тогда из вашего собственного ClassLoader вы сможете получить этот ресурс с помощью getResourceAsStream(...)

Комментарии:

1. Вы указываете использовать One-Jar или просто используете его для справки о том, как получить доступ к внутреннему содержимому jar?

2. Обратите внимание, что верхний файл — это не JAR, а EAR; это означает, что он имеет более сложный загрузчик классов, чем стандартный. Загрузчики классов EAR обрабатывают загрузку ресурсов из вложенных JAR и WARs на основе содержимого META-INF.

3. @Vladimir: в исходном вопросе этого не было указано. В OP не была учтена эта важная деталь в исходном вопросе. Нажмите на edited [time] ссылку под вопросом для получения подробной информации.