У меня есть простой проект, который читает файл ресурса .yaml:
var yamlObjectMapper = new ObjectMapper(new YAMLFactory());
var classLoader = Application.class.getClassLoader();
var file = new File(Objects.requireNonNull(classLoader.getResource("config.yaml")).getFile());
var appConfig = yamlObjectMapper.readValue(file, ApplicationConfig.class);
Так что из IDE работает нормально. Теперь я хочу создать исполняемый файл uber JAR, который будет включать все ресурсы внутри. Пользуюсь maven-shade-plugin.
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<transformers>
<transformer implementation = "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>mypackage.Application</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Итак, я ожидаю, что файлы ресурсов будут включены в jar. И когда я запускаю jar tf myapplication-0.0.1-SNAPSHOT.jar, я вижу, что внутри банки находится файл config.yaml. Однако, когда я пытаюсь запустить его с java -jar, я получаю java.io.FileNotFoundException с сообщением о том, что config.yaml не может быть найден.




Вот решение, предоставленное мне Андреа Боккаччи. Вот его ответ, который он разрешил мне опубликовать здесь:
Ваш файл находится внутри jar-файла, поэтому вы не можете получить к нему доступ из класса File, попробуйте использовать getResourceAsStream, а затем переключитесь на readValue(InputStream, Class), если есть такой API.
в противном случае вы можете записать входной поток в фактический временный файл, затем вызовите readValue(File, Class) и затем удалите извлеченный файл.
Вот как мой код выглядит сейчас и работает:
var yamlObjectMapper = new ObjectMapper(new YAMLFactory());
var classLoader = Application.class.getClassLoader();
var resource = classLoader.getResourceAsStrean("config.yaml");
var appConfig = yamlObjectMapper.readValue(resource, ApplicationConfig.class);