Search code examples
javamavenmulti-project

maven dependencies copied from dependent project after zip assemby


If this already has an answer, I haven't managed to find it. I have spent many hours getting this far, before throwing in the towel and asking here! When it comes to Maven, I would describe myself as a 'Sunday driver'.

Plugin versions: compiler=3.9.0; resurce and dependencies=3.2.0; jar=3.2.2; assembly=3.3.0.

I have two Maven projects, let's call then AppA and Proj1. Proj1 contains all of the 'working' code and 3rd party jar dependencies.

AppA contains the Main class and the app's folders such as 'conf' and 'logs'. Both projects have 'jar' packaging.

AppA's pom has the plugins required to create the jar file with a manifest that defines all of the required jar files in its classpath as 'lib/xxx.jar'. It also has 'Proj1' as a dependency.

The problem I have is that Maven is assembling the zip file before copying all of the dependent jars to the 'lib' folder. Which means that the 'lib' folder is missing from the zip file.

If I build AppA from a single project, the zip file is assembled after the 'lib' folder has been populated,

Can anyone advise me whatI need to do to persuade Maven to copy the dependent jar files to 'lib' before assembling the zip file?

The reason that I have this structure is so that I can create AppB + Proj1 in the future.

Also, the lib file contains all of the Maven plugin jars and their dependencies. When I buils from a single project, they are excluded.

[pom.xml]

<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>com.w3p.njams</groupId>
<artifactId>com.w3p.iib.njams.client</artifactId>
<version>Beta-1.0.1.0</version>
<packaging>jar</packaging>
<name>nJAMS Client App for IIB</name>
<description>nJAMS Client App for IIB</description>

<properties>
    <jdk.version>1.8</jdk.version>
    <maven.compiler.version>3.9.0</maven.compiler.version>
    <njams.client.version>Beta-1.0.1.0 </njams.client.version>
    <client.build.dir>njamsIIBClient</client.build.dir>
    <ibm.api.artifact>com.w3p.api.iib10</ibm.api.artifact>
    <ibm.api.version>Beta-1.0.1.0</ibm.api.version>
    <dependency.version>3.2.0</dependency.version>
    <resources.plugin.version>3.2.0</resources.plugin.version>
    <lifecycle.mapping.version>1.0.0</lifecycle.mapping.version>
    <!-- ** Logging ** -->
    <log4j.version>2.17.1</log4j.version>
    <disruptor.version>3.4.4</disruptor.version>
</properties>

<dependencies>

    <!-- ** Logging ** -->
    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>${log4j.version}</version>
        <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.lmax/disruptor -->
    <!-- for async logging -->
    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>${disruptor.version}</version>
    </dependency>

    <!-- ** The nJAMS Client common to IIB and ACE -->
    <dependency>
        <groupId>com.w3p.njams</groupId>
        <artifactId>com.w3p.njams.client</artifactId>
        <version>${njams.client.version}</version>
    </dependency>
    <!-- ** W3P's IIB/ACE API ** -->
    <dependency>
        <groupId>com.w3p.njams</groupId>
        <artifactId>${ibm.api.artifact}</artifactId>
        <version>${ibm.api.version}</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-dependency-plugin -->
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>${dependency.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-resources-plugin -->
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.2.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-assembly-plugin -->
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.3.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-source-plugin -->
    <dependency>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        <version>3.2.1</version>
    </dependency>
</dependencies>

<build>
    <!--        <pluginManagement>  -->
    <plugins>
        <!-- *** In Build Sequence *** -->
        <!-- Maven Resources Plugin  - copies resources fron Eclipse project folders to output build folder = cliemt-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>${resources.plugin.version}</version>
            <executions>
                <execution>
                    <id>copy-resources</id>
                    <!-- bind to the validate phase -->
                    <phase>validate</phase>
                    <goals>
                        <goal>copy-resources</goal>
                    </goals>
                    <configuration>
                        <includeEmptyDirs>true</includeEmptyDirs>
                        <outputDirectory>${project.build.directory}/${client.build.dir}_${project.version}</outputDirectory>
                        <nonFilteredFileExtensions>
                            <nonFilteredFileExtension>cache</nonFilteredFileExtension>
                            <!-- serialised FlowTtoProcessModelCache -->
                            <nonFilteredFileExtension>pmd</nonFilteredFileExtension>
                            <!-- serialised ProcessModels -->
                        </nonFilteredFileExtensions>
                        <resources>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/conf</targetPath>
                                <directory>conf</directory>
                                <filtering>true</filtering>
                                <exclude>log4j2-test.xml</exclude>
                                <exclude>njams*.xml</exclude>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/flowToProcessModelCache</targetPath>
                                <directory>flowToProcessModelCache</directory>
                                <filtering>true</filtering>
                                <include>dummy.cache</include>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/certs</targetPath>
                                <directory>certs</directory>
                                <filtering>true</filtering>
                                <include>dummy.cert</include>
                                <exclude>*-endpoint</exclude>
                                <exclude>*-instanceId</exclude>
                                <exclude>*.key</exclude>
                                <exclude>*.pem</exclude>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/logs</targetPath>
                                <directory>logs</directory>
                                <filtering>true</filtering>
                                <exclude>njams*.log</exclude>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/images</targetPath>
                                <directory>images</directory>
                                <filtering>false</filtering>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/jms</targetPath>
                                <directory>jms</directory>
                                <filtering>true</filtering>
                                <include>JNDI_Local/*.bindings</include>
                                <include>JNDI_Remote/*.bindings</include>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/monitoringProfiles</targetPath>
                                <directory>monitoringProfiles</directory>
                                <filtering>true</filtering>
                                <include>dummyProfile.xml</include>
                                <include>*.xsd</include>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/processModels</targetPath>
                                <directory>processModels</directory>
                                <filtering>true</filtering>
                                <include>dummy.pmd</include>
                            </resource>
                            <resource>
                                <targetPath>${project.build.directory}/${client.build.dir}_${project.version}/scripts</targetPath>
                                <directory>scripts</directory>
                                <filtering>false</filtering>
                            </resource>
                        </resources>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- ** Maven Compiler Plugin ** -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.version}</version>
            <configuration>
                <source>${jdk.version}</source>
                <target>${jdk.version}</target>
            </configuration>
        </plugin>

        <!-- Maven Dependency Plugin -> copies dependenciea to  'appName'_${project.varsion}  -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>${dependency.version}</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>install</phase>
                    <!-- prepare-package -->
                    <!-- waspacjage -->
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/${client.build.dir}_${project.version}/lib</outputDirectory>
                        <overWriteReleases>false</overWriteReleases>
                        <overWriteSnapshots>false</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                        <!-- The next line actually excludes the scope 'test' jars from the build -->
                        <includeScope>compile</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <!-- Maven Jar Plugin - Create the jar file and it's manifest entries -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.2</version>
            <configuration>
                <outputDirectory>${project.build.directory}/${client.build.dir}_${project.version}</outputDirectory>
                <finalName>${client.build.dir}-${project.version}</finalName>
                <excludes>
                    <!-- -->
                    <exclude>**/*.properties</exclude>
                    <exclude>**/*.xml</exclude>
                    <!-- -->
                </excludes>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.w3p.im.iib.mon.client.IIBMonitoringClient</mainClass>
                    </manifest>
                    <manifestEntries>
                        <Class-Path>. resources</Class-Path>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
        
        <!-- Maven Assembly Plugin -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>create-archive</id> <!-- this is used for inheritance merges -->
                    <phase>package</phase> <!-- append to the packaging phase. -->
                    <goals>
                        <goal>single</goal> <!-- goals == mojos -->
                    </goals>
                    <configuration>
                        <appendAssemblyId>false</appendAssemblyId>
                        <descriptors>
                            <descriptor>src/main/assembly/zip.xml</descriptor>
                        </descriptors>
                        <outputDirectory>${project.basedir}</outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>

    </plugins>
</build>

[zip.xml]

<assembly>
<id>zip</id>
<baseDirectory>/</baseDirectory>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
    <format>zip</format>
</formats>

<fileSets>
    <fileSet>
        <directory>${project.build.directory}/${client.build.dir}_${project.version}</directory>
        <outputDirectory>${client.build.dir}_${project.version}</outputDirectory>
    </fileSet>
</fileSets>

Solution

  • It happens because the maven-assembly-plugin executes on a prior phase (package) than the the maven-dependency-plugin phase (install). Try to set up the execution of the plugins so it will act as you expect.

    I would also suggest a different approach which I think can simplify you build configuration - use a multi-module pom which will aggregate both project. Than on the concrete pom.xml of AppA use Proj1 as a dependency. It will saves you from copying around files and repackage.