Maven использует то, что называется Стандартное расположение каталогов .Если вы не придерживаетесь этого макета, то плагины не могут выполнять свою работу правильно.Технически вы можете настроить Maven для использования разных каталогов, но в 99,999% случаев это не нужно.
Одна из особенностей этого макета заключается в том, что рабочие файлы входят в:
<project-dir>/src/main/java
<project-dir>/src/main/resources
- Все не
*.java
файлы (которые предназначены для ресурсов)
При создании проекта исходные файлы Java компилируются, а файлы *.class
помещаются в каталог target/classes
;это сделано maven-compiler-plugin
.Тем временем файлы ресурсов копируются из src/main/resources
в target/classes
;за это отвечает maven-resources-plugin
.
Примечание: См. Введение в жизненный цикл сборки для получения дополнительной информации о фазах и о том, какие подключаемые модули выполняются какимифаза.Этот вопрос переполнения стека также может быть полезен.
При запуске приложения из IDE (возможно, через exec-maven-plugin
) помещается каталог target/classes
в classpath. Это означает, что все скомпилированные классы из src/main/java
и все скопированные ресурсы из src/main/resources
доступны для использования через classpath.
Затем, когда вы упаковываете свое приложение в JARфайл, все файлы в target/classes
добавляются в получившийся файл JAR (обрабатывается maven-jar-plugin
). Сюда входят ресурсы, скопированные с src/main/resources
.Когда вы запускаете приложение, используя этот JAR-файл, ресурсы все еще доступны для использования через classpath, потому что они встроены в JAR-файл.
Чтобы сделать resource.txt
доступным в classpath, просто переместите:
<project-dir>/resource.txt
Кому:
<project-dir>/src/main/resources/resource.txt.
Тогда вы можете использовать Class#getResource
с /resource.txt
в качестве пути, и все должно сработать для вас.URL
, возвращаемый getResource
, будет отличаться в зависимости от того, выполняете ли вы против target/classes
или против файла JAR.
При выполнении против target/classes
вы получите что-то вроде:
file:///.../<project-dir>/target/classes/resource.txt
При выполнении с файлом JAR вы получите что-то вроде:
jar:file:///.../<project-dir>/target/projectname-version.jar!/resource.txt
Примечание: Все это предполагает, что resource.txt
фактически должнобыть ресурсом, а не внешним файлом.Ресурсы обычно доступны только для чтения после развертывания в файле JAR;если вам нужен доступный для записи файл, то вы можете использовать назначенное место для файла (например, папку в домашнем каталоге пользователя).Обычно доступ к внешним файлам осуществляется с помощью java.io.File
или java.nio.file.*
.Помните, что ресурсы - это не то же самое, что обычные файлы.
Теперь, если бы вы поместили resource.txt
прямо под <project-dir>
, это бы ничего не значило для Maven .Он не будет скопирован в target/classes
или не окажется в файле JAR, что означает, что ресурс никогда не будет доступен в classpath.Итак, просто для повторения, все ресурсы идут под src/main/resources
.
Проверьте Javadoc java.lang.Class#getResource(String)
для получения дополнительной информации о пути, напримеркак, когда использовать ведущий /
, а когда нет.Ссылка указывает на Javadoc для Java 12, который включает информацию о ресурсах и модулях (модули JPMS / Jigsaw, а не модули Maven);если вы не используете модули, вы можете игнорировать эту часть документации.