На каком этапе сборки Maven ресурсы копируются в директорию target?

Ответ

Ресурсы копируются в target на фазе process-resources (для main-ресурсов) и process-test-resources (для test-ресурсов) жизненного цикла default.

Стандартный путь копирования:

  • src/main/resourcestarget/classes
  • src/test/resourcestarget/test-classes

Почему именно на этой фазе? Потому что ресурсы (конфиги, свойства, XML) должны быть доступны в classpath до этапа компиляции (compile) и выполнения тестов (test).

Пример кастомизации в pom.xml:

<build>
    <resources>
        <resource>
            <!-- Указываем нестандартную директорию -->
            <directory>src/main/config</directory>
            <!-- Фильтрация (подстановка значений из properties) -->
            <filtering>true</filtering>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <!-- Можно исключать файлы -->
            <excludes>
                <exclude>**/secrets.*</exclude>
            </excludes>
        </resource>
    </resources>
</build>

Порядок фаз по умолчанию: validateinitializeprocess-resourcescompile → ...

Ответ 18+ 🔞

А, ну вот, слушай, сейчас я тебе такую простыню про ресурсы накатаю, что ты офигеешь, но зато всё поймёшь, блядь.

Так, значит, смотри. Есть у нас эти ваши src/main/resources и src/test/resources. Так вот, Maven — он не просто так, он по плану живёт, по фазам, как в армии. И есть у него фаза под названием process-resources. Вот на этой самой фазе, ёпта, для основных (main) ресурсов и происходит вся магия. А для тестовых — на фазе process-test-resources. Это типа их рабочий день, когда они копируют файлы.

Куда копируют, спросишь? Да всё просто, как три копейки:

  • src/main/resources летит прямиком в target/classes. Туда же, где и скомпилированные классы будут лежать, чтобы в classpath всё было.
  • src/test/resources — тот же принцип, но в target/test-classes.

А почему именно на этой фазе, а не на compile, например? А потому что, чувак, ресурсы-то (эти твои application.yml, logback.xml, картинки всякие) нужны ДО того, как компиляция начнётся и тесты побегут! Им же в classpath'е надо оказаться заранее. Логично? Логично, блядь.

Ну а если тебе стандартный путь не нравится — ну, бывает, мы все нестандартные. Maven это предусмотрел, хитрая жопа. Смотри, как в pom.xml можно всё перевернуть:

<build>
    <resources>
        <resource>
            <!-- Хочешь, чтобы ресурсы из папки 'config' брались? Пожалуйста! -->
            <directory>src/main/config</directory>
            <!-- Фильтрацию включить? Чтобы значения из properties подставлялись? Легко! -->
            <filtering>true</filtering>
            <includes>
                <!-- Бери только пропертяки и XML -->
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <!-- А вот секретные файлы, например, в репу не тащи, исключи их -->
            <excludes>
                <exclude>**/secrets.*</exclude>
            </excludes>
        </resource>
    </resources>
</build>

И чтобы ты совсем не запутался, вот тебе порядок фаз по умолчанию, как они идут друг за другом: validateinitializeprocess-resourcescompile → ... и так далее. Видишь, где наш герой? Прямо перед компиляцией, на своём законном месте. Всё, теперь ты гуру ресурсов, можешь идти и объяснять это всем остальным, у кого от Maven мозг вытекает.