Our main project is "common-core", an Ant project. This codebase is under constant development.
We have another project "batch" which is a Maven project. In this project we would like to use the "common-core" as a dependency.
I've tried doing something like this in the pom file:
<dependency>
<groupId>mydomain</groupId>
<artifactId>ibcore-with-dependencies</artifactId>
<version>current</version>
<scope>system</scope>
<systemPath>${project.basedir}/../common-core/bin/common-core-with-dependencies.jar</systemPath>
</dependency>
...
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<tasks>
<touch file="${project.basedir}/../common-core/bin/common-core-with-dependencies.jar" mkdirs="true" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>clean</id>
<phase>clean</phase>
<configuration>
<tasks>
<exec dir="${project.basedir}/../common-core/build" executable="ant" failonerror="true">
<arg line="clean" />
</exec>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>build</id>
<phase>process-resources</phase>
<configuration>
<tasks>
<exec dir="${project.basedir}/../common-core/build" executable="ant" failonerror="true">
<arg line="single-jar" />
</exec>
<copy todir="${project.build.directory}/lib"
file="${project.basedir}/../common-core/bin/common-core-with-dependencies.jar" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
But this doesn't work as the validation step fails if the common-core-with-dependencies.jar
doesn't exist before the build starts. That is, the touch
command happens too late.
The ant task in the process-resources
phase builds common-core and creates an all-in-one jar with common-core plus its dependencies.
Is there a way to have the validate step not fail because of the missing common-core-dependencies.jar or to execute an ant step before validate
?
I have a work-around to wrap the mvn build command within a script that executes touch
on the common-core-with-dependencies.jar
but I'm hoping to avoid that.
Edit:
I got something working using the information linked to by Blaine's answer but it still ended up being quite complicated.
common-core
has a lib directory containing build and test dependencies. These may not be the same versions that Maven would choose but they are known to work so that is what I want.
I added two new Ant targets into common-core
(for build and test-build) that creates super-jar files containing the content of all the dependent jars (or test-jars).
Unfortunately, a number of things go wrong with this:
Some of the jars were signed. I have to strip the signing files from META-INF
The various spring jars all contain the same META-INF/spring.* files. These need to be combined. I struggled to get Ant to deal with these duplicate names but got it going with a bit of a hack in the end.
Ant target code:
<target name="single-jar" depends="build"
description="Produce a single jar containing core-common plus all its dependencies for use by batch">
<jar destfile="${core-depends.jar}-temp" filesetmanifest="merge">
<fileset file="${core.jar}" includes="**/*.class"/>
<fileset dir="${core.src}" includes="**/*.properties" />
<zipgroupfileset dir="${core.lib}">
<include name="**/*.jar" />
<exclude name="notdeployed/**/*.jar" />
</zipgroupfileset>
</jar>
<!-- The combined jar file contains multiple instances of various spring.* files.
Many of these need to be concatenated into a single instance.
The only way I can think of to do this is to extract them with distinct names
before concatenating them -->
<delete dir="${core.bin}/spring" quiet="true"/>
<unzip src="${core-depends.jar}-temp" dest="${core.bin}/spring">
<patternset>
<include name="META-INF/spring.*"/>
</patternset>
<scriptmapper language="javascript">
self.addMappedName(source + '.' + (Math.random()));
</scriptmapper>
</unzip>
<mkdir dir="${core.bin}/spring"/> <!-- In case there was nothing to unzip -->
<concat destfile="${core.bin}/spring.schemas" fixlastline="true">
<fileset dir="${core.bin}/spring" includes="META-INF/spring.schemas.*" />
</concat>
<concat destfile="${core.bin}/spring.factories" fixlastline="true">
<fileset dir="${core.bin}/spring" includes="META-INF/spring.factories.*" />
</concat>
<concat destfile="${core.bin}/spring.handlers" fixlastline="true">
<fileset dir="${core.bin}/spring" includes="META-INF/spring.handlers.*" />
</concat>
<concat destfile="${core.bin}/spring.tooling" fixlastline="true">
<fileset dir="${core.bin}/spring" includes="META-INF/spring.tooling.*" />
</concat>
<jar destfile="${core-depends.jar}">
<zipfileset dir="${core.bin}" prefix="META-INF/" includes="spring.*" />
<zipfileset src="${core-depends.jar}-temp" excludes="META-INF/spring.schemas META-INF/spring.handlers META-INF/spring.factories META-INF/spring.tooling META-INF/**/*.SF, META-INF/**/*.DSA, META-INF/**/*.RSA"/>
</jar>
<delete dir="${core.bin}/spring" quiet="true"/>
<delete file="${core-depends.jar}-temp" />
<delete quiet="true">
<fileset dir="${core.bin}" includes="spring.*"/>
</delete>
</target>
It seems like you are trying to build a project AND reference it in the same pom. Instead, try creating a new pom that is dedicated specifically for the ant build. Then reference that project in this one as a dependency.
Here is an article that provides a very good explanation of this process: https://web.archive.org/web/20140227062842/http://devblog.virtage.com/2013/04/embed-and-run-ant-tasks-and-scripts-from-maven/