Using maven with external build scripts - maven

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>

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.

Related

How to maintain daily SNAPSHOT build using TeamCity in C# projects

I am taking over a project which consists of around 15 projects, whose continuous integration practice was done (the practice was ceased and I need to re-start it in a new environment) by Maven + Nexus OSS + TeamCity and are developed using C#.
What I got, except for those C# solutions themselves, is a POM for each of these project, and another parent POM (which doesn't contain any code) which every other project has parent of. These development POMs only have inter-dependency on SNAPSHOT versions hence the build order is crucial. But these POMs that I have do not need any VS plugin, which means (I guess) the compile procedure is not done by Maven but by TeamCity (VS runner). The Maven scripts I have are probably only in charge of e.g., downloading dependencies, validating and installing/deploying/releasing. Unfortunately I can't find any TeamCity configurations so I have no clue how this was done before.
EDIT:
I'll try to put some POM and script file that I have and see if someone can see some clue on the build procedure.
The files I got from SVN are mainly in three kinds categories:
1) The C# source code and project/solution files. Each solution has a 'Dependency' folder which contains all the dependencies, both on other projects on third-party dlls, so that this solution can be built in VS by the developer right after he checkout this solution.
2) The (development) POMs.
Firstly I have the POM of the parent project. This project doesn't contain any code but only the POM and some scripts (other projects have similar files too). The POM looks like this:
<modelVersion>4.0.0</modelVersion>
<groupId>MY.GROUP</groupId>
<artifactId>configuration</artifactId>
<version>1.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Configuration</name>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>purge-local-dependencies</id>
<phase>clean</phase>
<goals>
<goal>purge-local-repository</goal>
</goals>
<configuration>
<!-- Whether to purge only snapshot artifacts. -->
<snapshotsOnly>true</snapshotsOnly>
<actTransitively>false</actTransitively>
<reResolve>false</reResolve>
</configuration>
</execution>
<execution>
<id>unpack-dependencies</id>
<phase>validate</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${dependencies.directory}</outputDirectory>
<markersDirectory>${dependencies.markers.directory}</markersDirectory>
<useBaseVersion>true</useBaseVersion>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<excludeTransitive>false</excludeTransitive>
<useSubDirectoryPerArtifact>true</useSubDirectoryPerArtifact>
<stripVersion>true</stripVersion>
<stripClassifier>true</stripClassifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>assembly-single-zip</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>${project.build.finalName}</finalName>
<descriptors>
<descriptor>${assembly.file}</descriptor>
</descriptors>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<executions>
<execution>
<id>deploy-file-snapshot</id>
<phase>verify</phase>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<file>${deploy.file}</file>
<repositoryId>${nexus.repository.id}</repositoryId>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<url>${nexus.repository.url}</url>
<pomFile>${nexus.deploy.pom}</pomFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<preparationGoals>clean</preparationGoals>
<tagBase>${release.tagBase}</tagBase>
<tagNameFormat>#{project.version}</tagNameFormat>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
...
Here we see that the plugins used in the build are dependency (to download dependencies), 'assembly' (to package), deploy (to deploy files to Nexus) and release--frankly I can't figure out how it is used. The scripts that I have (I'll describe later) don't use it explicitly and it doesn't seem to be executed in other standard build phases.
And in each of the solution the POM has parent of the configuration. And they look like this:
ProjA
<parent>
<groupId>MY.GROUP</groupId>
<artifactId>configuration</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<groupId>MY.GROUP</groupId>
<artifactId>ProjA</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>ProjA</name>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
</plugin>
</plugins>
</build>
...
In ProjB which depends on ProjA, the POM is like this:
<parent>
<groupId>MY.GROUP</groupId>
<artifactId>configuration</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>
<groupId>MY.GROUP</groupId>
<artifactId>ProjB</artifactId>
<version>1.2.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>ProjB</name>
...
<dependencies>
<dependency>
<groupId>MY.GROUP</groupId>
<artifactId>ProjA</artifactId>
<version>1.1.2-SNAPSHOT</version>
<type>zip</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
</plugin>
</plugins>
</build>
...
3) Then some .bat scripts as well as deploy.pom and release.pom.
The deploy pom and release pom just simply replace the version numbers and declare the dependencies:
deploy.pom for ProjA:
<?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
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>MY.GROUP</groupId>
<artifactId>ProjA</artifactId>
<version>1.1.2-SNAPSHOT</version>
<packaging>pom</packaging>
..<dependencies>...</dependencies>
By deploy I assume it means the the deployment of SNAPSHOT version as the version number indicates.
And the release.pom are basically the same but change the version to release version (in ProjA it is 1.1.1).
In each solution I also have some scripts which I believe are called by TeamCity. a) a file called download.bat, which basically calls mvn -U clean and then mvn -U validate. And b) a file called upload.bat which basically calls mvn prepare-package and then mvn verify. In both scripts we pass some mvn options like -DDeployPomFile, -DNexusUrl, -DRepositoryId. From the parent POM we can see some plugins are executed in those scripts too. And I guess the download.bat is called before TC is executing the VS build and upload.bat is called after the build (assume the target of the build is to publish the latest version).
Above is all I got. I suspect I still miss some TeamCity configuration because they are not stored in the SVN. But anyway, can somebody help figure out how to manage the daily build? Thank you very much!

How to use maven shade to build jar and war

I'm on a project working with openrdf, and I require the shade plugin to transform my service entries. I would like to build a war and a jar simultaneously, as both usages are possible. However, I cannot get the shade plugin to produce a shaded jar and a shaded war at the same time - shade only invokes on the package type defined in the properties, and binding e.g. the jar plugin to the package phase in order to create a jar next to the war results in an unshaded jar. How can I create both a shaded jar and a shaded war at the same time?
If by "shaded war" you mean just the regular war with all dependencies packed into WEB-INF/lib, then you might just use maven-war-plugin separately and use jar as packaging type. This way shade plugin will work correctly. And .war will be built by plugin.
Below is pom.xml. And here is working example.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>so.test</groupId>
<artifactId>stackoverflow-test2</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.build.finalName}-fatjar</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.14.9</version>
</dependency>
</dependencies>
</project>

Tycho Compiler not picking up generated source code

I am fairly new to the world of maven and tycho, so hopefully this is just something obvious that I am missing. I am trying to build a plugin using tycho but I am unable to get the tycho-compiler-plugin to recognise source code that is generated as a part of the build process.
Here is a copy of a test pom that I've put together to demonstrate:
<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>rt</groupId>
<artifactId>rt.webservice</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tycho-version>0.16.0</tycho-version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-compiler-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<verbose>true</verbose>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<executions>
<execution>
<id>generate-ws-code</id>
<phase>generate-sources</phase>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlDirectory>${basedir}/wsdl</wsdlDirectory>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I have a java class in the src folder that references some of the generated source code, which then fails to compile.
If I remove tycho and use the standard maven-compiler-plugin, it automatically picks up the code generated during the build and the java class mentioned above compiles as expected.
Can someone tell me what I am doing wrong?
tycho compiler plugin uses source dirs configured in build.properties
you have to make sure the generated source dir is referenced in build.properties
http://jax-ws-commons.java.net/jaxws-maven-plugin/wsimport-mojo.html#sourceDestDir
You have to add additional source folders for generated sources, in your case the wsdl dir.
See this question for help on that.
Tycho will then pick up those additional directories during compile.

Use jarsign plugin with assembly plugin in Maven 3

I'm using assembly plugin to package a list of applets into zip in one of modules with my maven project. here is the pom.xml:
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<artifactId>applets-deploy</artifactId>
<name>deploy</name>
<dependencies>
<dependency>
<groupId>com.activx.lims</groupId>
<artifactId>applets-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.activx.lims</groupId>
<artifactId>ceplot-applet</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
......
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/resources.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
what I need is to also sign jars before they are packaged, can I use jarsign plugin here, and how? I can't find where the jar files are temporarily stored during the build process.
Thanks,
This would be a pretty normal use of the jarsigner plugin. By default, jars are built by the jar plugin during the package phase and output to the ${project.build.directory}, which defaults to target.
You'd just need to sign the jars some time after they're built during package and before you assemble the zip. You could do that by binding the assembly plugin to a later phase or by adding the jarsigner plugin above the assembly plugin and binding it to the package phase, too.

Maven install plugin with depedency packaging

I have Project A and Project B. ProjectB just has only proprietary jars or third party libs that ProjectA needs which cannot be found in maven repository. I intended to package all the related ( grouping dependencies) jars of Project B into one/more jar files. Question is, how do I install these jars and shade/assemble them in to one jar at the same time using POM. I am getting proprietary jars installed separately but I cannot get them packaged them in to one jar. M2 eclipse is also not helping much , so I decide to use mvn commands inside eclipse. What is the best practice to do this?. I think shading them since I want to use these dependencies in other projects as well.Can I install and shade/assemble jars( logically group the related dependencies in to one jar) at the time using POM?.
I followed this( from stack over flow forum) , it did not work- as this is creating one project jar which doesn't have anything + proprietary jars separately but not shading all jars in to one. I want them installed and combined in to one jar at the same time.
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.projectdeps</groupId>
<artifactId>sharedlibs</artifactId>
<version>1.0-SNAPSHOT</version>
<name>shared-libs</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>install activationjar</id>
<goals><goal>install-file</goal></goals>
<phase>validate</phase>
<configuration>
<file>${basedir}/src/main/libs/activation.jar</file>
<groupId>com.mycompany.activation</groupId>
<artifactId>activation</artifactId>
<version>12.8</version>
<packaging>jar</packaging>
</configuration>
</execution>
<execution>
<id>install opsjar</id>
<goals><goal>install-file</goal></goals>
<phase>validate</phase>
<configuration>
<file>${basedir}/src/main/libs/Operations.jar</file>
<groupId>com.mycompany.gcs.ops</groupId>
<artifactId>Operations</artifactId>
<version>12.8</version>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>Operations</artifact>
<includes>
<include>/**</include>
</includes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.5</version>
<type>maven-plugin</type>
</dependency>
</dependencies>
</project>

Resources