← Назад к вопросам

Попадут ли ресурсы в Target в Maven

2.0 Middle🔥 91 комментариев
#Другое

Комментарии (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.jarJAR архив (содержит всё из 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:

  1. Стандартная структура: src/main/resources/target/classes/
  2. Фаза сборки: process-resources копирует файлы
  3. В JAR архиве: Ресурсы остаются в корне архива
  4. Доступ: Через ClassLoader.getResourceAsStream()
  5. Фильтрация: Переменные из pom.xml подставляются в ресурсы
  6. Best Practice: Храни конфиги в src/main/resources/, не в коде
Попадут ли ресурсы в Target в Maven | PrepBro