Dependencies' jar-s copied by maven-dependency-plugin aren't installed to local repository

302 views Asked by At

There are modules A, B and C. Module A is a dependency for modules B and C. All jar-s built in the module A are to be distributes into Maven Central but only after integration tests in modules B and C are passed.

To achieve the goal above, I decided to implement a multi-module project with a dedicated module D just for distribution.

As the distribution module D has its own specific coordinates, jar-s from module A are to be renamed.

My idea was to copy jar-s from module A as dependencies to the target dir of the module D with renaming according to the module D coordinates. Here's the module D pom:

<parent>
    <groupId>...</groupId>
    <artifactId>parent</artifactId>
    <version>0.1.0-SNAPSHOT</version>
</parent>

<groupId>...</groupId>
<artifactId>...</artifactId>
<packaging>pom</packaging>

...

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>...</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${project.artifactId}-${project.version}.jar</destFileName>
                            </artifactItem>
                            <artifactItem>
                                <groupId>...</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <classifier>sources</classifier>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${project.artifactId}-${project.version}-sources.jar</destFileName>
                            </artifactItem>
                            <artifactItem>
                                <groupId>...</groupId>
                                <artifactId>...</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <classifier>javadoc</classifier>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${project.artifactId}-${project.version}-javadoc.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

jar-s are copied from the module A to the module's D target directory but only module's D pom is updated in my local repository after install phase is completed. There are no records about installing of copied jar-s in build log either.

At the same time, jar-s from module A are successfully installed.

I tried to change packaging of the module D to jar, but only jar with binaries was installed after that, and jar-s with sources and javadoc weren't installed.

At the moment the following workaround is found:

<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <phase>install</phase>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <configuration>
                        <file>${project.build.directory}/${project.artifactId}-${project.version}.jar</file>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                        <packaging>jar</packaging>
                        <javadoc>
                            ${project.build.directory}/${project.artifactId}-${project.version}-javadoc.jar
                        </javadoc>
                        <sources>
                            ${project.build.directory}/${project.artifactId}-${project.version}-sources.jar
                        </sources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Is there any other less clumsy solution?

Thanks.

2

There are 2 answers

0
Thed On

It turns out that it's not enough just to copy needed jar-s to target, but those jar-s are to be additionally attached using build-helper-maven-plugin.

So, here's the parent pom (a bit simplified to be consistent with the question details and for the sake of clearness):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="http://maven.apache.org/POM/4.0.0"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0      http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example.internal</groupId>
<artifactId>parent</artifactId>
<version>0.1.0-SNAPSHOT</version>
<packaging>pom</packaging>

<modules>
    <module>A</module>
    <module>B</module>
    <module>C</module>
    <module>D</module>
</modules>

</project>

Here's the pom of the distributed module D (a bit simplified as well):

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

<groupId>com.example</groupId>
<artifactId>D</artifactId>
<packaging>pom</packaging>

<properties>
    <moduleToDistributeGroupId>com.example.internal</moduleToDistributeGroupId>
    <moduleToDistributeArtifactId>A</moduleToDistributeArtifactId>
    <sourcesClassifier>sources</sourcesClassifier>
    <javadocClassifier>javadoc</javadocClassifier>
    <binaryArtifactName>${project.artifactId}-${project.version}.jar</binaryArtifactName>
    <sourcesArtifactName>${project.artifactId}-${project.version}-${sourcesClassifier}.jar</sourcesArtifactName>
    <javadocArtifactName>${project.artifactId}-${project.version}-${javadocClassifier}.jar</javadocArtifactName>
</properties>

<dependencies>
    <dependency>
        <groupId>com.example.internal</groupId>
        <artifactId>A</artifactId>
    </dependency>
    <dependency>
        <groupId>com.example.internal</groupId>
        <artifactId>B</artifactId>
        <version>${project.version}</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.example.internal</groupId>
        <artifactId>C</artifactId>
        <version>${project.version}</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>3.1.1</version>
            <executions>
                <execution>
                    <id>copy</id>
                    <phase>package</phase>
                    <goals>
                        <goal>copy</goal>
                    </goals>
                    <configuration>
                        <artifact>
                        </artifact>
                        <artifactItems>
                            <artifactItem>
                                <groupId>${moduleToDistributeGroupId}</groupId>
                                <artifactId>${moduleToDistributeArtifactId}</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${binaryArtifactName}</destFileName>
                            </artifactItem>
                            <artifactItem>
                                <groupId>${moduleToDistributeGroupId}</groupId>
                                <artifactId>${moduleToDistributeArtifactId}</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <classifier>${sourcesClassifier}</classifier>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${sourcesArtifactName}</destFileName>
                            </artifactItem>
                            <artifactItem>
                                <groupId>${moduleToDistributeGroupId}</groupId>
                                <artifactId>${moduleToDistributeArtifactId}</artifactId>
                                <version>${project.version}</version>
                                <type>jar</type>
                                <classifier>${javadocClassifier}</classifier>
                                <overWrite>true</overWrite>
                                <outputDirectory>${project.build.directory}</outputDirectory>
                                <destFileName>${javadocArtifactName}</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>build-helper-maven-plugin</artifactId>
            <version>3.2.0</version>
            <executions>
                <execution>
                    <id>attach-artifacts</id>
                    <phase>package</phase>
                    <goals>
                        <goal>attach-artifact</goal>
                    </goals>
                    <configuration>
                        <artifacts>
                            <artifact>
                                <file>${project.build.directory}/${binaryArtifactName}</file>
                                <type>jar</type>
                            </artifact>
                            <artifact>
                                <file>${project.build.directory}/${sourcesArtifactName}</file>
                                <classifier>${sourcesClassifier}</classifier>
                                <type>jar</type>
                            </artifact>
                            <artifact>
                                <file>${project.build.directory}/${javadocArtifactName}</file>
                                <classifier>${javadocClassifier}</classifier>
                                <type>jar</type>
                            </artifact>
                        </artifacts>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <!--other plugins-->
    </plugins>
</build>

</project>

After artifacts are attached they're automatically recognized by all other plugins, e.g., gpg, install, deploy, etc.

4
J Fabian Meier On

The approach is overly complicated.

What you should do instead:

  • build A
  • test A with B and C
  • deploy A

Depending on your approach, there are different possibilities to achieve this. You could e.g. use the property deployAtEnd of the maven deploy plugin.