Maven deploy: deployment should fail if artifact already exists - maven

If I configure my pom.xml as below:
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<serverId>nexus</serverId>
<nexusUrl>https://nexus/</nexusUrl>
<skipStaging>false</skipStaging>
</configuration>
</plugin>
Then what happens is that on executing mvn deploy -this will deploy projectName-1.0-20180323.065217-1.jar on Nexus and the next deployment will have projectName-1.0-20180323.065217-2.jar deployed on nexus.
Is it possible to check if the snapshot version (in this case 1.0) is already present in nexus repo (and it gives a fail message that the version cannot be deployed).
The deployed version should be named as projectName-1.0.jar instead of projectName-1.0-20180323.065217-1.jar

The mvn deploy will fail if the artifact to be uploaded is already in the repository
Note: only if you upload as a "RELEASE", not a "SNAPSHOT".
Your build could check first if that release version exists:
mvn dependency:get -Dartifact=g:a:v -o -DrepoUrl=file://path/to/your/repo

Related

Preventing Maven Modules from being Deployed

I followed this tutorial to created a Maven build that can publish artifacts to Maven Central.
It works, and most of the tutorial is for authentication of some sort, so the only relevant part of it might just be:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<id>default-deploy</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
Now I wanted to only deploy two of the seven modules in total, so I added this to the parent POM:
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
And <skip>false</skip> to the two modules I actually want to deploy.
This doesn't work. All modules get deployed.
I checked the effective POM, and it clearly shows skip=false for the two modules I want to deploy and skip=true for the other five modules.
Since deploying to Maven Central isn't really a reversible process, I don't want to trial and error my way through this problem, hence the question: How do I prevent Maven modules from deploying to Maven Central?
If you are deploying to Maven Central, it is the Nexus Staging Plugin that is doing the deployment instead of the Deploy plugin, so the configuration of the deploy plugin has no effect. To make the Nexus deploy plugin skip, set skipNexusStagingDeployMojo in its configuration to true.
For a complete example, you can look at one of my projects I deployed to Maven Central with the same problem - I want to deploy everything except the integration test modules.
In the parent POM, the Nexus deploy plugin is defined like normal as described in the tutorial (https://bitbucket.org/prunge/shoelaces/src/2347535282c9f5bb58d33cca22d9dd65c9db2c2b/pom.xml#pom.xml-200):
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
</configuration>
</plugin>
and in the integration tests project (which itself has children that inherit this configuration) the staging plugin is skipped (https://bitbucket.org/prunge/shoelaces/src/2347535282c9f5bb58d33cca22d9dd65c9db2c2b/integration-tests/pom.xml#pom.xml-28):
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
</configuration>
</plugin>
This results in everything by default being deployed to Central except the integration tests project and everything underneath that.

Sonatype nexus publish snapshot, but unable to download

I am struggling with the upload of a SNAPSHOT artifact to Sonatype oss. I am able to upload the artifact: https://oss.sonatype.org/content/repositories/snapshots/com/github/st-h/vertx-mongo-streams/2.1.0-SNAPSHOT/
However, when I try to use that library as a dependency, it always tries to download a version which does not exist. for instance this is my latest build error:
Could not determine the dependencies of task ':shadowJar'.
> Could not resolve all dependencies for configuration ':runtimeClasspath'.
> Could not find com.github.st-h:vertx-mongo-streams:2.1.0-SNAPSHOT.
Searched in the following locations:
- https://oss.sonatype.org/content/repositories/snapshots/com/github/st-h/vertx-mongo-streams/2.1.0-SNAPSHOT/vertx-mongo-streams-2.1.0-20181221.154759-9.pom
- https://oss.sonatype.org/content/repositories/snapshots/com/github/st-h/vertx-mongo-streams/2.1.0-SNAPSHOT/vertx-mongo-streams-2.1.0-20181221.154759-9.jar
Required by:
project :
The latest version available is *-8. However, Gradle tries to download *-9
this is the latest config of the nexus-stagign-maven-plugin
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.3</version>
<extensions>true</extensions>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>deploy</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<autoReleaseAfterClose>false</autoReleaseAfterClose>
<skipStagingRepositoryClose>true</skipStagingRepositoryClose>
<autoDropAfterRelease>false</autoDropAfterRelease>
</configuration>
</plugin>
However, I previously had tried using it with just autoReleaseAfterClose enabled, but that shows the same error.
The timestamp in Nexus is off by one second. So I think problem is likely to be this Apache Maven bug:
https://issues.apache.org/jira/browse/MNG-6240
with root cause of this:
https://issues.apache.org/jira/browse/MDEPLOY-221
If you're not running Apache Maven version 3.5.2 or higher try upgrading Maven.

Build a site zip with Maven

actually, I generate a maven site containing the documentation of my project. It works very well, in fact if works so well that my customers wants to get that site as a deliverable (for obvious documentation purpose).
How can I tell Maven to build a zip of the whole site and deploy it to my artifacts manager (Nexus)? I've tried several things, but if I understand correctly, deploying artifacts and generating the site are using different livecycle, and the site generation occurs after the deployment of the artifacts..
I could obviously get the generated site from the location it's deployed during site-deploy, but I would greatly appreciate an automatic and centralized way...
PS: giving access to the customer to our internal site is NOT an option.
Here is a working solution delegated to a Maven profile to isolate the behavior (and speed-up normal builds), but which could also be integrated in the default build if required (although not recommended).
<profiles>
<profile>
<id>site-zip</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.4</version>
<executions>
<execution>
<id>pack-site</id>
<phase>prepare-package</phase>
<goals>
<goal>site</goal>
<goal>jar</goal>
</goals>
<configuration>
<attach>false</attach>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>rename-file</id>
<phase>prepare-package</phase>
<goals>
<goal>rename</goal>
</goals>
<configuration>
<sourceFile>${project.build.directory}/${project.build.finalName}-site.jar</sourceFile>
<destinationFile>${project.build.directory}/${project.build.finalName}-site.zip</destinationFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<goals>
<goal>attach-artifact</goal>
</goals>
<phase>package</phase>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}-site.zip</file>
<type>zip</type>
<classifier>site</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
What the profile is actually doing:
Configuring an execution of the Maven Site Plugin, attached to the prepare-package phase and running the site and jar goals (as also suggested by #khmarbaise).
Renaming the file from jar to zip via the Copy Rename Maven Plugin
Attaching the zip to the build via the Build Helper Maven Plugin and its attach-artifact goal
As such, running
mvn clean install -Psite-zip
Will also install in your local Maven cache the zipped site. The deploy phase would do the same on your target Maven repository then.
Note that the Maven Site Plugin and the Copy Plugin must be declared in the order above to follow the required flow within the same phase.
Also note that if zip is not a strong requirement, you can then just skip the Copy and Build Helper executions and only use the Maven Site execution. By default the jar created providing the site is already attached to the build (and hence it will be installed and deployed automatically). In order to have the zip, we had to disable this behavior (<attach>false</attach>) and re-attach it via the Build Helper plugin.
The generated zipped has automatically a classifier, which is site in this case.
You can use the maven-site-plugin.

I want to automatically update artifact version with the latest svn revision number using maven release plugin

My artifact version looks like this:
1.0.0-SNAPSHOT
I want to use the maven release plugin to deploy the artifact to the releases repository, using the following version: 1.0.0.1234, where 1234 is the latest svn revision number.
Is this possible?
I tried to retrieve the svn revision number using org.codehaus.mojo:buildnumber-maven-plugin and adding the following section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<configuration>
<releaseVersion>1.0.0.${buildNumber}</releaseVersion>
</configuration>
</plugin>
But when I run the following command:
mvn -DdryRun=true -Dresume=false -B release:prepare
It looks like the version is set to 1.0.0.${buildNumber} in the tag instead.
The problem is that you have associated the goal buildnumber-maven-plugin:create associated with the phase validate. If you want that it is executed and thus, the variable ${buildNumber} is given value by the time you are executing release:prepare, you have to execute the phase beforehand.
That said, in order to make it work, you have to change your command for this one:
mvn validate -DdryRun=true -Dresume=false -B release:prepare

Unpack an EAR file using maven

I have an EAR file from some build. I want to extract the contents of this EAR file into another folder. I am confused how to do this. I have looked and tried
http://maven.apache.org/plugins/maven-ear-plugin/
and
http://maven.apache.org/plugins/maven-dependency-plugin/usage.html
but either maven is unable to find the file or it has dependency issues.
Since I am new to maven I don not understand how to set these plugins up.
I got the following error on using the below plugin.
Failure to find ECM:ECM:ear:1.0 in http://repo.maven.apache.org/maven2 was cached in the local repository
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
You can do it using dependency:unpack-dependencies. I just modify my answer because according to your comments, your ear is generated by some other build. If you do not have an Enterprise repository that you can deploy your ear artifact, you have to use "system" scope, but please note that it is usually discouraged.
Add below dependency to your pom.xml
<dependency>
<groupId>ECM</groupId>
<artifactId>ECM</artifactId>
<version>1.0</version>
<type>ear</type>
<scope>system</scope>
<systemPath>/path/to/your/abc.ear</systemPath>
</dependency>
Add the below plugin to your postBuild module pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>ECM</includeArtifactIds>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Have you looked at this example of Maven EAR plugin for Unpacking a module yet?
The Maven Dependency Plugin and its unpack goal can do this.
Sample configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>myear</groupId>
<artifactId>myear</artifactId>
<version>1.0</version>
<type>ear</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/earoutput</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
This takes the 'myear.ear' artifact and extracts it to the 'target/earoutput' directory. This also works with JARs, WARs and any other zip-like file. The phase this executes under is 'package' - this may be too late if you need to use these resources in other parts of the build. Change the phase to something earlier such as 'generate-resources' if needed.
You mentioned that you already tried using the dependency plugin. Is the EAR file from another Maven project, and has it been installed in the local Maven repository? If it still doesn't work post the plugin configuration you tried to use.
(edit: update information on dependencies and local repository)
For this to work, your EAR file needs to be put into your local Maven repository (this is just a directory on your disk). But if other people need to build your project as well, you have a few options:
import the EAR into your local repository, and also deploy to a remote repository so everyone can get it (recommended, but requires you to set up a corporate Maven repository)
give the EAR to everyone and have them put it into their local repository using a couple of Maven commands (might be OK for a few developers, less overhead than setting up a whole repository server)
check the dependent EAR into source control under your project and unpack it (not the recommended way of doing things) in a goal in your project
Importing into your local repository is easy. It's very similar to these instructions.
Use the following command:
mvn install:install-file -Dfile=<path-to-EAR-file-on-local-filesystem> -DgroupId=myear
-DartifactId=myear -Dversion=1.0 -Dpackaging=ear
(modify path, groupId, artifactId and version as needed)
Group ID and artifact ID are there simply to uniquely identify artifacts.
Once you install this in the local repository, the dependency plugin should work and find the artifact.

Resources