Maven-dependency-plugin: unpack игнорирует конфигурацию типа

Есть два независимых проекта Maven. Нет ни общего родителя, ни POM-файлов-агрегаторов.

Второй проект нуждается в некоторых классах, предоставленных shared-tests. Точнее, я бы повторно использовал некоторые общие тестовые случаи в зависимом проекте и запускал их на этапах test и integration-test.

Первый проект (shared-tests) содержит несколько общих тестовых случаев.

<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>io.github.zforgo.stackoverflow</groupId>
    <artifactId>shared-tests</artifactId>
    <version>0.1.0-SNAPSHOT</version>
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.release>11</maven.compiler.release>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.7.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.2.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
</project>

После запуска

mvn чистая установка

Тестовая банка хранится рядом с производственной банкой.

spinner@zaphod:~/.m2/repository/io/github/zforgo/stackoverflow/shared-tests/0.1.0-SNAPSHOT$ ll
total 28
drwxrwxr-x 2 spinner spinner 4096 Dec 20 15:16 ./
drwxrwxr-x 3 spinner spinner 4096 Dec 20 15:16 ../
-rw-rw-r-- 1 spinner spinner  931 Dec 20 15:23 maven-metadata-local.xml
-rw-rw-r-- 1 spinner spinner  248 Dec 20 15:23 _remote.repositories
-rw-rw-r-- 1 spinner spinner 3183 Dec 20 15:23 shared-tests-0.1.0-SNAPSHOT.jar
-rw-rw-r-- 1 spinner spinner 3299 Dec 20 14:41 shared-tests-0.1.0-SNAPSHOT.pom
-rw-rw-r-- 1 spinner spinner 3961 Dec 20 15:23 shared-tests-0.1.0-SNAPSHOT-tests.jar

Второй проект определяет shared-tests как тестовую зависимость, и на этапе generate-test-sources он пытается распаковать.

<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>io.github.zforgo.stackoverflow</groupId>
    <artifactId>project</artifactId>
    <version>0.1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>io.github.zforgo.stackoverflow</groupId>
            <artifactId>shared-tests</artifactId>
            <version>0.1.0-SNAPSHOT</version>
            <type>test-jar</type>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>3.1.2</version>
                <executions>
                    <execution>
                        <id>share-tests</id>
                        <phase>generate-test-sources</phase>
                        <goals>
                            <goal>unpack</goal>
                        </goals>
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>io.github.zforgo.stackoverflow</groupId>
                                    <artifactId>shared-tests</artifactId>
                                    <version>0.1.0-SNAPSHOT</version>
                                    <type>test-jar</type>
                                    <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Но когда я бегу

мвн установить

Производственный артефакт shared-tests будет распакован вместо тестовой банки.

[INFO] ---------------< io.github.zforgo.stackoverflow:project >---------------
[INFO] Building project 0.1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO] 
[INFO] --- maven-dependency-plugin:3.1.2:unpack (share-tests) @ project ---
[INFO] Configured Artifact: io.github.zforgo.stackoverflow:shared-tests:0.1.0-SNAPSHOT:test-jar
[INFO] Unpacking /home/spinner/.m2/repository/io/github/zforgo/stackoverflow/shared-tests/0.1.0-SNAPSHOT/shared-tests-0.1.0-SNAPSHOT.jar to /work/source/stackoverflow/junit-test-sharing/test-jar/project/target/alternateLocation with includes "" and excludes ""
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

На основании логов нужный артефакт настроен

Настроенный артефакт: io.github.zforgo.stackoverflow:shared-tests:0.1.0-SNAPSHOT:test-jar

Но не тот был распакован.

Распаковка [...]/shared-tests/0.1.0-SNAPSHOT/shared-tests-0.1.0-SNAPSHOT.jar в ...

Это баг или есть возможность распаковать test-jar в другой проект? Вероятно, использование <classifier/> может быть решением, но оно не предназначено для указания типа артефакта.

Неправильный путь. Просто определите во втором проекте зависимость с соответствующим классификатором, см. maven.apache.org/plugins/maven-jar-plugin/examples/… нет необходимости использовать зависимость: распаковать...

khmarbaise 20.12.2020 16:32

@khmarbaise спасибо за подсказку, но, насколько я знаю, мне этого недостаточно. Это определение просто позволяет использовать (например, импортировать или расширять) классы артефактов, но я хотел бы повторно запустить эти распакованные тестовые примеры в зависимом модуле.

zforgo 20.12.2020 16:40

Если у вас есть два независимых проекта Maven, но вы повторно используете тесты, похоже, что они принадлежат друг другу в многомодульной сборке, или вам нужно изменить тесты, как они работают. Проблема при запуске модульных тестов заключается в том, что они ищутся и выполняются в текущем модуле. Чтобы решить вашу проблему, вы должны настроить maven.apache.org/surefire/maven-surefire-plugin/… для сканирования тестов на зависимости... и сохранить настройку test-jar, как я описал...

khmarbaise 20.12.2020 17:00

Кроме того, если у вас есть один и тот же тест, это означает, что, скорее всего, у вас одинаковая функциональность, что означает, что вы можете реорганизовать код из двух проектов... и результатом будет только один набор тестов.

khmarbaise 20.12.2020 17:10

Сначала большое спасибо dependenciesToScan подсказка. Надеюсь, это поможет. Я просто ищу возможности улучшить наше тестовое покрытие. Иногда это может быть полезно. Например. интеграционный тест, который проверяет существование конечной точки мониторинга и так далее. К счастью, maven-failsafe-plugin также может сканировать зависимости. Вы совершенно правы, почти всегда рефакторинг — это реальное решение, но иногда совместное тестирование — это возможность. Снова танки.

zforgo 20.12.2020 17:28
Не удалось выполнить цель org.apache.maven.plugins
Не удалось выполнить цель org.apache.maven.plugins
Опишу, что когда я только начинал изучать Maven, у меня не получалось компилировать и упаковывать.
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Blibli Automation Journey - Как захватить сетевой трафик с помощью утилиты HAR в Selenium 4
Если вы являетесь веб-разработчиком или тестировщиком, вы можете быть знакомы с Selenium, популярным инструментом для автоматизации работы...
1
5
389
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После некоторой отладки кажется, что это ошибка.

Цель unpack хорошо считывает конфигурацию и создает объект ArtifactItem с правильными параметрами. Но когда он создает объект Artifact на основе ArtifactItem, параметр типа не был установлен, и будет использоваться значение по умолчанию (jar).

Исходный код можно найти здесь.

Связанная часть:

   protected Artifact getArtifact( ArtifactItem artifactItem )
        throws MojoExecutionException
    {
        Artifact artifact;

        try
        {

            // ...

            ProjectBuildingRequest buildingRequest = newResolveArtifactProjectBuildingRequest();

            if ( localRepositoryDirectory != null )
            {
                buildingRequest =
                    repositoryManager.setLocalRepositoryBasedir( buildingRequest, localRepositoryDirectory );
            }

            // Map dependency to artifact coordinate
            DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
            coordinate.setGroupId( artifactItem.getGroupId() );
            coordinate.setArtifactId( artifactItem.getArtifactId() );
            coordinate.setVersion( artifactItem.getVersion() );
            coordinate.setClassifier( artifactItem.getClassifier() );

            // ...


            artifact = artifactResolver.resolveArtifact( buildingRequest, coordinate ).getArtifact();
        }
        catch ( ArtifactResolverException e )
        {
            throw new MojoExecutionException( "Unable to find/resolve artifact.", e );
        }

        return artifact;
    }

В то время

            // Map dependency to artifact coordinate
            DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();

Устанавливает тип java в качестве значения по умолчанию, которое никогда не обновлялось. Об этом поведении сообщается здесь: MDEP-732

Обходной путь может использовать <classifier> вместо <type>, например:

<!-- ... -->
                        <configuration>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>io.github.zforgo.stackoverflow</groupId>
                                    <artifactId>shared-tests</artifactId>
                                    <version>0.1.0-SNAPSHOT</version>
                                    <!-- note: classifier must be tests not test-jar -->
                                    <classifier>tests</classifier>
                                    <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
<!-- ... -->

Другие вопросы по теме