Installing maven generated artifacts without using the artifactId - maven

I have a maven parent project with 2 modules. When building the parent project, I want to generate and install the final artifact with a different name than the artifactId used in the pom.xml. I can see that the artifact generated does have the name that I want use in the build dir. However when the archive is installed in the local Maven repository, the maven-install-plugin copies the artifacts using the project's artifactId. How can I configure the plugin to install the artifacts without using the artifactId?
My child project's pom.xml:
<project>
<parent>
<groupId>com.mycomp</groupId>
<artifactId>com-mycomp</artifactId>
<version>12.0.0.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycomp</groupId>
<artifactId>child1</artifactId>
<version>12.0.0.0.0</version>
<build>
<defaultGoal>install</defaultGoal>
<finalName>${parent.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<outputDirectory>${project.build.directory}/dependencies/</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>assembly:package</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/resources/dependencies.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<classpathPrefix>libs/</classpathPrefix>
<addClasspath>true</addClasspath>
<mainClass>com.my.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
The parent pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycomp</groupId>
<artifactId>com-mycomp</artifactId>
<version>12.0.0.0.0</version>
<packaging>pom</packaging>
<modules>
<module>child1</module>
<module>child2</module>
</modules>
:
:
</project>
The desired output of mvn clean install:
1) com-mycomp-12.0.0.0.0.jar in the local maven repository
2) com-mycomp-12.0.0.0.0.zip comprising of the above jar and its dependencies.
The observed behavior:
3) com-mycomp-12.0.0.0.0.jar is created in the build dir. But it is installed in the maven repository as child1-12.0.0.0.0.jar
4) com-mycomp-12.0.0.0.0.zip is created in the build dir. But it is installed in the maven repository as child1-12.0.0.0.0.zip
How can I achieve the desired behavior (#1 and #2) ?

Artifacts in the local repository are always installed with their artifactId.
You cannot change that. And even if you could, I would strongly recommend against that because you are breaking expectations.
If you want to create an additional zip that contains the jar with dependencies, you don't need a second module. You can create it through the assembly plugin and attach it with a classifier like dependencies. You then have two artifacts like
com-mycomp-12.0.0.0.0.jar
com-mycomp-12.0.0.0.0-dependencies.zip

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 install only pom with Maven install-plugin with minimal configuration

I am using the Maven (2.2.1) install-plugin (2.5.2) to install third party dependencies not available in the repository.
When the dependency has both a jar and a pom, install-plugin reads the pom file and sets the packaging, groupId, artifactId, and version so I don't need to specify them:
<execution>
<id>1</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>si/odm/jrules-engine/8.5.1/jrules-engine-8.5.1.jar</file>
<pomFile>si/odm/jrules-engine/8.5.1/jrules-engine-8.5.1.pom</pomFile>
</configuration>
</execution>
However, when the dependency has only a pom file, it forces me to specify the packaging, groupId, etc. manually:
<execution>
<id>2</id>
<phase>validate</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<packaging>pom</packaging>
<groupId>odm</groupId>
<artifactId>jrules-otherthing</artifactId>
<version>8.5.1</version>
<file>si/odm/jrules-otherthing/8.5.1/jrules-otherthing-8.5.1.pom</file>
</configuration>
</execution>
Is it possible to configure install-plugin to read the pom file when it is the only file being installed?
Being able to do this would make the configuration a great deal shorter and more readable.
I tried specifying the pom file in the <pomFile> element without a <file> element, but install-plugin insists that I must have a <file>. I assume this isn't currently possible, but I wanted to ask here in case I missed something.
To follow on from others' comments, Here is how I used maven-install-plugin to install only a pom into my repo using Maven 3.6.1:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
<configuration>
<groupId>com.microservice</groupId>
<artifactId>parent</artifactId>
<version>${revision}</version>
<packaging>pom</packaging>
<file>pom.xml</file>
</configuration>
<executions>
<execution>
<id>install-pom</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>

Why Maven generates a maven directory in a jar when two jars are merged?

I've merged sources from two artifacts/jars into separate single jar using assembly plugin. However, looking at the content of the new jar file at META-INF/maven there is a maven directory which contains packages from both of those jars.
Few questions:
1 - What is the purpose of that META-INF/maven dir?
2 - How/who generate that file and why?
3 - Is there an option to remove it from the archive and how?
4 - What is the impact if we removed it from the archive?
Here is my plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>merge-two-jars</id>
<phase>prepare-package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>com.ibm.scope.ext.system.agent-${scope.release}-${ibm.build.number}</finalName>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/ppk-agent-merge-agent-common.xml</descriptor>
</descriptors>
<archive>
<manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</execution>
</executions>
.....
Informational purpose - maven feature
Maven for informational purpose
For JAR, EAR, and WAR Plugins. Use <archive><addMavenDescriptor>false</addMavenDescriptor></archive> to exclude META-INF/maven, MWAR-27
No impact
Overriding Manifest
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
[...]
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
[...]
</plugin>
[...]
</project>
More about Maven Manifest: Maven Archiver

Get build number/date from artifact when building with maven

I use maven to build some projects which are installed into local .m2 and a remote artifactory repository.
I have another project that downloads (maven-dependency-plugin:copy) some of these artifacts to its local target folder and then uploads them to a fileshare. When I upload the artifact to fileshare I need to give it a buildNumber which should not change if I re-run the project. How do I get the buildnumber for a artifact in eg. artifactory?
When I browse the artifacts in artifactory they all have unique buildIds.
The best solutin might be to use buildnumber-maven-plugin to get the information from VCS etc. and put this information into the manifest.mf file. You can continue using the maven-dependency-plugin:copy goal to copy artifacts into the appropriate folder. Only in case you have SNAPSHOT's you might later take a look into the jar itself.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>true</doCheck>
<doUpdate>true</doUpdate>
</configuration>
</plugin>
</plugins>
</build>
You can define what should be put into the MANIFEST.MF file like the following:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.1</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Maven multimodules w. assembly options per module?

I've a multimodule maven setup, where I'd like to pack one of the jars with their dependencies and all others could stay as they are. My configuration looks like this:
Root:
<project...>
<modelVersion>4.0.0</modelVersion>
<name>Foo</name>
<artifactId>Foo</artifactId>
<groupId>org.example</groupId>
<version>1.0</version>
<packaging>pom</packaging>
<modules>
<module>Bar1</module>
<module>Bar2</module>
<module>Bar3</module>
</modules>
</project>
Module (Bar1):
<project...>
<modelVersion>4.0.0</modelVersion>
<name>Foo - Bar1</name>
<artifactId>Bar1</artifactId>
<groupId>${project.parent.groupId}</groupId>
<parent>
<artifactId>Foo</artifactId>
<groupId>org.exmaple</groupId>
<version>1.0</version>
</parent>
<build>
<finalName>Bar1</finalName>
<plugins>
...
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>org.exmaple.bar1.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
...
</plugins>
</build>
</project>
With that running mvn package would give me all jar/war files for the modules. But to generate the jar with dependencies I have to switch into the module and trigger the assembly in addition cd Bar1; mvn assembly:single.
Is there any chance to change the setup so that after mvn package one of the jars is build with dependencies included?
Cheers.
Include the assembly plugin to the execution of the package phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
<finalName>apache-maven-cookbook-${pom.version}</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
As described on maven assembly page
You need to define an execution for the assembly plugin. Otherwise it won't be executed. The site of the plugin may be a bit misleading as there is a section on configuration which looks like yours. But if you want the execution to actually happen, you need to define it.

Resources