Не могу прочитать весенний загрузочный файл упаковки - PullRequest
0 голосов
/ 05 января 2019

Среда: Ubuntu 18 + Spring boot 2.0 + JDK 11

Он работает правильно, когда приложение работает в IntelliJ, но не работает при чтении файла после файла упаковки подключаемого модуля Spring boot maven.

PS: файл действительно может быть найден в упакованном jar-файле!

java.io.FileNotFoundException: class path resource [jmxremote.password] 
cannot be resolved to absolute file path because it does not reside in the 
file system: jar:file:/home/XXX/YYY/target/YYY-1.0-Final.jar!/BOOT-
INF/classes!/jmxremote.password

Ответы [ 2 ]

0 голосов
/ 05 января 2019

TL; DR

В среде Spring Framework основное внимание уделяется использованию служебных программ Spring для обработки ресурсов (например, ResourceUtils class ), которые красиво инкапсулируют низкоуровневые операции ввода-вывода, зависящие от операционной системы. ResourceUtils уже содержит несколько ловушек, чтобы выяснить, является ли запущенный вами проект в разобранном виде (запущен в IDE) или упакован (внутри файла JAR).


Ответ, предоставленный Каролом, кажется самым простым и относительно пуленепробиваемым, пока вам не понадобится определенный уровень гибкости для указания местоположения файла (внутри файла JAR, но с возможностью определять его внешне и предоставлять где-то в файловой системе). ). Тогда подход с методом getResourceAsStream() не будет работать.

Стандартный Java IO (java.nio) использует FileSystemProvider классы для делегирования операций ввода-вывода (таких как создание, чтение и удаление файлов).

Поставщик определяется по схеме URI . Поставщик по умолчанию идентифицируется схемой URI «файл». Он создает файловую систему, которая обеспечивает доступ к файловым системам, доступным для виртуальной машины Java. Класс FileSystems определяет, как расположены и загружаются поставщики файловой системы.

Итак, если ваш файл находится где-то в файловой системе, проблем нет, и все работает нормально. Технически, URL, возвращаемый Application.class.getResource("").toURI(), начинается с file: // и содержит допустимый путь к файловой системе.

Сказав, что, когда ваш файл "приземляется" внутри файла jar, Application.class.getResource("").toURI() возвращает что-то более похожее на file: // {jar-location}! / (обратите внимание на восклицательный знак), который не является допустимым путем к схеме файла, и Java не знает, как его обработать. Дополнительный поставщик файловой системы нуждается в регистрации.

FileSystems.newFileSystem(uri, emptyMap());

Java вычисляет (на основе URI) схему и регистрирует новую файловую систему. Отныне могут использоваться стандартные файловые операции java.nio.

Например, если у вас есть файлы в папке / webapp , которые могут (но не обязательно) находиться внутри файла jar, и вы хотите перечислить их.

// Load zip specific filesystem provider when run from inside a fat-jar
URI uri = Application.class.getResource("").toURI();
if (uri.toString().contains("!")) {
    FileSystems.newFileSystem(uri, emptyMap());
}

URI rootFolder = Application.class.getResource("/webapp").toURI();
List<Path> banners = Files.list(Paths.get(rootFolder))
        .collect(Collectors.toList());

Random rand = new Random();
Path path = banners.get(rand.nextInt(banners.size()));

log.info("Random image: {}", path.getFileName());
byte[] bytes = Files.readAllBytes(path);

Установка нового поставщика файловой системы является глобальной и должна выполняться только один раз.

0 голосов
/ 05 января 2019

Скорее всего, вы пытаетесь использовать java.io классы для загрузки ресурса пути к классам. Это не будет работать, классы java.io предназначены только для операций с файловой системой.

Либо извлеките jmxremote.password за пределы JAR, либо используйте обычный InputStream для доступа к нему в качестве ресурса пути класса, например, используя Class.getResourceAsStream():

try (InputStream in : getClass().getResourceAsStream("/jmxremote.password")) {
  // read input
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...