Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Да, ресурсы попадут в Target в Maven. Это стандартное поведение
Ресурсы в Maven — это файлы (конфиги, свойства, XML, JSON и т.д.), которые необходимы приложению во время выполнения. Maven копирует их в target как часть процесса сборки.
Структура проекта Maven
my-project/
├── src/
│ ├── main/
│ │ ├── java/ ← Java исходный код
│ │ │ └── com/example/
│ │ │ └── App.java
│ │ └── resources/ ← Ресурсы (будут в target/classes)
│ │ ├── application.properties
│ │ ├── logback.xml
│ │ └── data/
│ │ └── config.json
│ └── test/
│ ├── java/ ← Тестовый код
│ │ └── AppTest.java
│ └── resources/ ← Тестовые ресурсы (будут в target/test-classes)
│ └── test-data.xml
├── target/
│ ├── classes/ ← Скомпилированные классы + РЕСУРСЫ
│ │ ├── com/
│ │ │ └── example/
│ │ │ └── App.class
│ │ ├── application.properties ← Копия из src/main/resources
│ │ ├── logback.xml ← Копия из src/main/resources
│ │ └── data/
│ │ └── config.json
│ ├── test-classes/ ← Скомпилированные тесты + тестовые ресурсы
│ │ ├── AppTest.class
│ │ └── test-data.xml
│ └── my-app-1.0.jar ← JAR архив (содержит всё выше)
└── pom.xml
Процесс сборки Maven (Lifecycle)
Мaven выполняет фазы в определённом порядке:
mvn clean install
│
├── clean (удаляет target/)
│
├── validate (проверка валидности проекта)
├── compile (компиляция java → .class файлы)
├── process-resources (КОПИРОВАНИЕ РЕСУРСОВ в target/classes) ← ЗДЕСЬ!
├── process-test-resources (копирование тестовых ресурсов)
├── test-compile (компиляция тестов)
├── test (запуск тестов)
├── package (создание JAR/WAR файла)
├── verify (проверка интеграции)
├── install (установка в локальный репозиторий ~/.m2)
└── deploy (загрузка на удалённый репозиторий)
Конфигурация ресурсов в pom.xml
По умолчанию (стандартная структура)
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0</version>
<!-- Maven автоматически ищет ресурсы здесь -->
<!-- <build>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build> -->
</project>
Кастомная конфигурация
<project>
<build>
<resources>
<!-- Основные ресурсы -->
<resource>
<directory>src/main/resources</directory>
<targetPath>config</targetPath> ← Копировать в target/classes/config
<includes>
<include>*.properties</include>
<include>*.xml</include>
</includes>
</resource>
<!-- Исключение некоторых файлов -->
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>*.tmp</exclude>
<exclude>secrets/*</exclude>
</excludes>
</resource>
<!-- Включение файлов с переменными (filtering) -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> ← Подставляет переменные из pom.xml
</resource>
</resources>
<!-- Тестовые ресурсы -->
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
</build>
</project>
Пример с фильтрацией ресурсов
pom.xml
<project>
<groupId>com.example</groupId>
<artifactId>my-app</artifactId>
<version>1.0.0</version>
<name>MyApp</name>
<description>My Application</description>
<properties>
<db.host>localhost</db.host>
<db.port>5432</db.port>
<db.name>myapp</db.name>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> ← Включаем фильтрацию
</resource>
</resources>
</build>
</project>
src/main/resources/application.properties (до обработки)
app.name=${project.name}
app.version=${project.version}
app.description=${project.description}
database.host=${db.host}
database.port=${db.port}
database.name=${db.name}
target/classes/application.properties (после обработки)
app.name=MyApp
app.version=1.0.0
app.description=My Application
database.host=localhost
database.port=5432
database.name=myapp
Как приложение использует ресурсы
import java.io.*;
import java.util.Properties;
public class ConfigLoader {
// Способ 1: Через классный лоадер (из classpath)
public static void loadFromClasspath() throws IOException {
Properties props = new Properties();
// application.properties находится в target/classes/
try (InputStream input = ConfigLoader.class.getClassLoader()
.getResourceAsStream("application.properties")) {
if (input != null) {
props.load(input);
String dbHost = props.getProperty("database.host");
int dbPort = Integer.parseInt(props.getProperty("database.port"));
System.out.println("БД хост: " + dbHost);
System.out.println("БД порт: " + dbPort);
}
}
}
// Способ 2: Через InputStream
public static void loadFromFile() throws IOException {
Properties props = new Properties();
try (InputStream input = new FileInputStream("src/main/resources/application.properties")) {
props.load(input);
}
}
// Способ 3: Через класс (как ресурс)
public static InputStream loadXmlResource() {
return ConfigLoader.class.getResourceAsStream("/logback.xml");
}
}
Где находятся ресурсы в разных местах
| Место | Содержит |
|---|---|
src/main/resources/ | Ресурсы приложения |
target/classes/ | Скомпилированные классы + копии ресурсов (при запуске) |
src/test/resources/ | Ресурсы для тестов |
target/test-classes/ | Скомпилированные тесты + тестовые ресурсы |
target/my-app.jar | JAR архив (содержит всё из target/classes/) |
Проверка наличия ресурсов в JAR
# Распаковать JAR и посмотреть содержимое
unzip -l target/my-app.jar | grep -i "application.properties"
# Вывод:
# Archive: target/my-app.jar
# Length Date Time Name
# -------- ---------- ----- ----
# 254 2024-03-15 10:30 application.properties
Практический пример: Spring Boot приложение
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
public class Application {
@Value("${database.host}")
private String dbHost;
@Value("${database.port}")
private int dbPort;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// Spring автоматически загрузит application.properties
// из target/classes/ (или из JAR при продакшене)
}
}
Частые проблемы
1. Ресурсы не копируются в target
# Решение: Убедитесь в правильной структуре
src/main/resources/ ← Должна существовать
# И перестройте проект
mvn clean compile
2. Файлы в нужной папке, но не в target
# Проверьте pom.xml — может быть неправильная конфигурация
# Решение:
mvn clean process-resources # Явно запустить фазу копирования
3. Переменные не подставляются
<!-- Убедитесь, что filtering включен -->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering> ← ВАЖНО!
</resource>
</resources>
</build>
Вывод
Да, ресурсы ВСЕГДА попадают в Target при сборке Maven:
- Стандартная структура:
src/main/resources/→target/classes/ - Фаза сборки:
process-resourcesкопирует файлы - В JAR архиве: Ресурсы остаются в корне архива
- Доступ: Через
ClassLoader.getResourceAsStream() - Фильтрация: Переменные из
pom.xmlподставляются в ресурсы - Best Practice: Храни конфиги в
src/main/resources/, не в коде