Java getResourceAsStream JAR внутри WAR
У меня есть файл WAR веб-приложения Java, который зависит от нескольких jar-файлов в его каталоге WEB-INF\lib. Один из этих JARS должен загрузить некоторые файлы конфигурации, выполнив class.getClassLoader().getResourceAsStream(...)
, Однако InputStream возобновляет нулевое значение. Есть ли проблема с этим подходом, когда JAR находится внутри WAR? Приложение развернуто на Tomcat6.
РЕДАКТИРОВАТЬ БОЛЬШЕ ИНФОРМАЦИИ:
Я пытаюсь загрузить SQL-запросы из файлов, чтобы я мог их запустить. Они расположены в отдельном банке DAO в WAR-файле веб-приложения под WEB-INF/lib.
mywebapp.war
-- WEB-INF
-- lib
-- mydao.jar
---- com/companyname/queries
-- query1.sql
-- query2.sql
-- query3.sql
...
Использование кода для загрузки классов
public class QueryLoader {
private static final Logger LOGGER = Logger.getLogger(QueryLoader.class.getName());
public String loadQuery(String fileName) {
final String newline = "\n";
BufferedReader reader = new BufferedReader(new InputStreamReader(
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
Я также попытался изменить строку getResourceAsStream на
Thread.currentThread().getContextClassLoader().getResourceAsStream(
безуспешно.
Моя среда разработки MS Windows Vista, но я сталкиваюсь с той же ошибкой при запуске в этой среде и в Ubuntu.
3 ответа
Удалось заставить его работать, используя вместо этого загрузчик ресурсов Spring
public String loadQuery(String fileName) {
final String newline = "\n";
ApplicationContext ctx = new ClassPathXmlApplicationContext();
Resource res = ctx.getResource("classpath:/com/msi/queries/" + fileName);
BufferedReader reader;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(res.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append(newline);
}
} catch (IOException e) {
LOGGER.error(e);
}
return sb.toString();
}
Предполагая, что вы не делаете ошибку новичка, помещая QueryLoader
в другом JAR единственная проблема, которую я вижу, это то, что вы используете File.separator
пока появляются (от вашего использования \
) использовать Windows. Когда используешь getResourceAsStream
, разделитель всегда является косой чертой (/
) так же, как если бы вы использовали URL.
Если я изменю это, я получу это:
QueryLoader.class.getClassLoader().getResourceAsStream(
"/com/companyname/queries/" + fileName)
Конечно, если QueryLoader
находится в com.companyname.queries
пакет (вместе с самими запросами), то вы должны просто сделать это:
QueryLoader.class.getResourceAsStream(fileName)
Просто как тот. (Документально подтверждено, что Class.getResourceAsStream
относит относительные имена файлов к имени содержащего пакета.)
Это должно работать, но вы должны позаботиться о том, чтобы вы использовали правильный загрузчик классов.