Search code examples
mavenmaven-install-plugin

Using maven with external build scripts


My application depends on a third-party ear (it deconstructs it, adds/modifies some items therein, and reconstructs it into a new ear). The third-party ear must be built using a third-party build script.

I am trying to learn the "maven-y" way to set this up. I expect I will need to get the third-party ear installed into my repository.

I want to create a pom.xml for the third-party ear which will build the third-party ear and install/deploy it. I have created a pom.xml which successfully calls out to the third-party build script (via maven-antrun-plugin) and creates the ear in exactly the place that a default maven ear project would.

My problem is that maven's install plugin fails because it can't find the archive (it expects whatever plugin does the packaging to have set an attribute on the artifact object, which maven-antrun-plugin doesn't do).

mvn package works fine and generates the ear.

The exact error message when running mvn install looks like this:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.3.1:install (default-install) on project third_party_ear: The
packaging for this project did not assign a file to the build artifact -> [Help 1]

Is there a better way to go about this?

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.thirdparty</groupId>
    <artifactId>third_party_ear</artifactId>
    <version>9.0</version>
    <packaging>ear</packaging>

    <name>third_party_ear</name>

    <build>
        <plugins>
            <plugin>
                <artifactId>maven-ear-plugin</artifactId>
                <version>2.6</version>
                <executions>
                    <execution>
                        <id>default-ear</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>default-generate-application-xml</id>
                        <phase>none</phase>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.7</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <configuration>
                            <target>
                                <subant target="build-ear" antfile="build.xml" buildpath="${project.basedir}"/>
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Solution

  • When you specify <packaging>ear</packaging> you are telling Maven to invoke the full lifecycle specified for that packaging.

    In your case what you want to do is write a wrapper pom.xml that just shells out to your 3rd party build script without invoking the EAR lifecycle and attach the produced artifact to Maven's reactor...

    Something like this should work

    <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.thirdparty</groupId>
        <artifactId>third_party_ear</artifactId>
        <version>9.0</version>
        <packaging>pom</packaging>
    
        <name>third_party_ear</name>
    
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <version>1.7</version>
                    <executions>
                        <execution>
                            <phase>package</phase>
                            <configuration>
                                <target>
                                    <subant target="build-ear" antfile="build.xml" buildpath="${project.basedir}"/>
                                    <attachartifact file="${project.build.directory}/${project.build.finalName}.ear" type="ear"/>
                                </target>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    

    There may be some slight glitches because the pom's packaging differs... but as this is not a classpath relevant artifact they shouldn't affect you.

    Note the attachartifact ANT task can attach an artifact from anywhere, so you need not have battled ANT to get the file in the "right" place... though it is nicer to follow that convention. You may want to not use the project.build.finalName and hardcode the filename.