Зачем использовать java .lang.ClassLoader.getResource для ресурса внутри jar - PullRequest
0 голосов
/ 19 июня 2020

Использование Java 8, Tomcat 8 +.

Я столкнулся с такой проблемой - я пытаюсь прочитать ресурс txt внутри jar в lib. Я использовал следующий код:

import java.io.File;
import org.apache.commons.io.FileUtils;

// ....    
// code within some class method
File file = new File(superService.getClass().getClassLoader()
                    .getResource("com/domain/example/sorry/confidential/little_text.txt")
                    .getFile())
return FileUtils.readFileToString(file, "UTF-8")

Хотя он хорошо работал с моей Intellij IDEA, после развертывания на сервере Tomcat у меня возникло такое исключение:

java .io.FileNotFoundException: файл 'файл: /usr/local/tomcat/webapps/prod-lims/WEB-INF/lib/abc-1.2-SNAPSHOT.jar! com / domain / example / извините / конфиденциально / little_text .txt 'не существует

И после этого я нашел много ответов в SO и других сайтах, которые мне нужно использовать методы ClassLoader.getResourceAsStream () или Class.getResourceAsStream () для ресурсов в JAR . Конечно, я попытался переработать свой код в старом стиле и - вуаля! - теперь работает:

import java.io.BufferedReader;
import java.io.InputStreamReader;

// ....    
// code within some class method
InputStream inputStream = superService.getClass().getClassLoader()
               .getResourceAsStream("com/domain/example/sorry/confidential/little_text.txt")


StringBuilder resultStringBuilder = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))
    try {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
        }
        } catch(Exception e) {
        //just a formal catch - don't mind for now
    }

return resultStringBuilder.toString()

Хорошо, рабочим решением доволен. Но я нигде не могу найти четкого объяснения: почему getResourceAsStream работает, и в то же время подход «Файл» не работает для ресурсов в JAR? Мне любопытно, потому что superService.getClass().getClassLoader().getResource("com/domain/example/sorry/confidential/little_text.txt") возвращает не null, но в созданном файле есть canRead() == false и isExist() == false.

1 Ответ

2 голосов
/ 19 июня 2020

File, FileInputStream, FileUtils и т. Д. Предназначены для доступа к файловой системе, и «файл», встроенный в JAR, на самом деле не является файлом с точки зрения файловой системы. Таким образом, вы можете получить доступ к этим встроенным файлам только с помощью инструментов, которые на самом деле предназначены для чтения изнутри архива (в основном JAR - это просто причудливый ZIP-файл).

Между прочим, тот факт, что ваш объект File в Java не равно нулю, это не означает, что файл действительно существует. Вы могли бы сделать это нормально:

File file = new File("I:\\do\\not.exist");

и file будут ненулевыми (но isReadable() и isExist() должны быть ложными). То же самое и с вашим ресурсом.

Вероятно, это работает в среде IDE, потому что файл действительно существует как неархивированный файл в вашей рабочей области.

...