zforgo
zforgo

Reputation: 3316

maven-dependency-plugin:unpack ignores type configuration

There are two independent Maven projects. There isn't neither common parent nor aggregator POM files.

The second project needs some classes provided by shared-tests. More precisely I'd re-use some common test cases in dependent project and run them during test and integration-test phases.

The first project (shared-tests) contains some shared test cases.

<?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>

After running

mvn clean install

the test jar has stored alongside production jar.

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

The second project defines the shared-tests as a test-scoped dependency and during generate-test-sources phase it tries to unpack.

<?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>

But when I run

mvn install

the production artifact of shared-tests will be unpacked instead of test-jar.

[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] ------------------------------------------------------------------------

Based on the logs the desired artifact has been configured

Configured Artifact: io.github.zforgo.stackoverflow:shared-tests:0.1.0-SNAPSHOT:test-jar

but the wrong one was unpacked.

Unpacking [...]/shared-tests/0.1.0-SNAPSHOT/shared-tests-0.1.0-SNAPSHOT.jar to ...

Is this a bug or is there any possibility to unpack test-jar into an other project? Probably using <classifier/> can be a solution but that is not made to specify type of an artifact.

Upvotes: 1

Views: 571

Answers (1)

zforgo
zforgo

Reputation: 3316

After some debugging it seems this is a bug.

The unpack goal reads configuration well and creates an ArtifactItem object with the right parameters. But when it creates an Artifact object based on ArtifactItem the type parameter wasn't set and the default value (jar) will used.

Source code can be found here.

Related part is:

   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;
    }

While the

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

sets type to java as a default value it never updated. This behaviour reported here: MDEP-732

Workaround can be using <classifier> instead of <type> like:

<!-- ... -->
                        <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>
<!-- ... -->

Upvotes: 1

Related Questions