Maven3 and Jenkins: Deploying multiple classifer - maven

we are currently migrating from maven2 to maven3.
Now we have a problem with the new "SNAPSHOT" policy of maven3 in one of our shared projects.
The project provides different configuration using filters to set different setting for different environments (dev, int, production) which are devided throw classifier.
In our Jenkins buildserver produces and deploy this three classifier in our local company repo: The dev in the main maven goal, the others as post steps.
In maven2 this was no problem, because after the deployment we had in our repository:
artifact-1.2.0-SNAPSHOT-dev.jar
artifact-1.2.0-SNAPSHOT-int.jar
artifact-1.2.0-SNAPSHOT-prod.jar
With maven3 we have now this timestamped versions:
artifact-1.2.0-20140212.103043-1-dev.jar
artifact-1.2.0-20140217.174231-2-int.jar
artifact-1.2.0-20140311.125512-3-prod.jar
Now the build of the other projects with the classifier dev or int breaks, because the lastest SNAPSHOT version is the 3rd one (prod) and the dev and int cannot be resolved from our repository.
As far as I know it's not possible to tell maven3 to deploy the "good old" SNAPSHOT without a timestamp. Is there a solution to process all configuration inside one maven3 call? Or how can we configure Jenkins to do that all as "one SNAPSHOT"?
Thanks in advance
Update 1
As followed the Post steps are configured:
Maven Goals:
Maven Version: 3.1.1
Goals: clean deploy -Pint
Maven Goals:
Maven Version: 3.1.1
Goals: clean deploy -Pprod

This won't work as you have planned. As you said, there is no way to use non timestamped repositories in Maven 3.
You have two options:
Either adapt your build in a way that creates all classifiers in one build (possibly by using different modules instead of different classifiers)
Or create a your own deploy mechanism.
I would strongly recommend solution 1.

From my understanding the artifacts generated from Maven 3 are coming with timestamp in their name like artifact-1.2.0-20140212.103043-1-dev.jar which are causing the failure of dependent builds.
As you need Maven 3 to generated artifacts with naming convention artifact-1.2.0-SNAPSHOT-dev.jar , this can be achieved by using "finalName" tag in the corresponding POM.xml which are generating these artifacts .
Controlling maven final name of jar artifact
Regards
Jyotsna

Related

Automated deployment of EAR project without obtain dependencies from a repository

Is it possible deploy an artifact (.ear) into a application server (AS) without obtain its dependencies from a repository?
Let's me explain: the maven project I'm trying to configure for deploy into a AS has 3 modules:
Web (.war - front end)
EJB (.ejb - back end)
Entity (.jar - entities classes)
These modules are wrapped into a EAR module and none of then are available in some repository (like Nexus or JFrog Artifactory). When I try to use Cargo Maven plugin or JBoss Deployment Maven Plugin, both notify that cannot resolve dependencies for these modules.
UPDATED (03/01/2019)
The issue is similar to that quoted in items 6 and 7 of the following link: http://webdev.jhuep.com/~jcs/ejava-javaee/coursedocs/content/html/ejb-basicex-eardeploy.html#ejb-basicex-eardeploy-testmodule
It's a workaround but worked. Instead of the project depends on an internal repository (like Nexus or JFrog Artifactory), it's possible defines a folder as a repository on the local machine using the Maven's parameter -Dmaven.repo.local. Thus, the plugin to deploy the artifact also can use this property and obtaining the others artifacts.
That is, to build the application on the current folder:
mvn -Dmaven.repo.local=. package
To deploy the application (.ear, in this case) using Cargo Maven Plugin, for example, without depending on an internal repository:
mvn -pl app-ear/ -Dmaven.repo.local=. cargo:redeploy
OBS: Using the maven.repo.local property, the folder defined as value will be fill with all dependencies of the project. In my case, it isn't a problem because this commands are been used on a continuous integration pipeline and all files and folder are discard on the final.

Jenkins: deploying war files from artifactory

We are using Jenkins to build (maven) & deploy artifacts (JARs & *WAR*s) to an in-house artifactory server (both snapshots and releases).
For deployment, currently, we got Jenkins jobs that package the war file (from a release scm tag) and deploy to different environments/servers. We want to skip the package phase as it seems unnecessary to package it again & again for a released version because it's not possible to get a different copy of war file even after trying 1000 times.
We are looking for a way in Jenkins to get the artifact (war) from Artifactory and deploy it to a container. I am sure other people would have faced this situation too but I am not able to find any online material regarding this.
Is there any Jenkins plugin that takes a war file from Artifactory (based on a version) and deploy it to a remote container?
If this is not the right way of doing it then what are the recommendations for any other approach?
Thanks
I don't know about a plugin which takes a version # and deploys that, but you can build a Jenkins job to deploy the last successful release to a previous environment (thus copying from DEV-->QA for example.)
To do this, you would use the copy-artifact-plugin.
Here's an easy to follow run-through of this kind of setup:
http://www.lordofthejars.com/2012/09/deploying-jee-artifacts-with-jenkins.html
Every artifact stored in Artifactory will have a unique URL that includes the version number. It will take the format
http://artifactory-server/repository-name/path-to-artifact/version/filename
e.g.
http://artifactory/apps-releases-local/com/yourorg/yourapp/1.5.67/webapp.war
(depending on how you do your packaging, the WAR file name may include the version number as well).
So your deployment job can construct the Artifactory URL and download the file. Depending on how you have security set up in Artifactory, you may need to authenticate the request.

Maven deploy multi module project only if all modules build successfully

I have a maven multi module project with several modules. I want to deploy them (mvn deploy) only if they all pass a full mvn install (which includes the tests).
Currently, I run a mvn install on the project. If all modules pass, I run mvn deploy to do the deployment. The problem I see is the waste of time calling mvn twice (even if I skip tests on the second run).
Does anyone have an idea on this?
EDIT: I have learned that using Artifactory as a repository manager and the maven-artifactory-plugin with your maven setup will add the atomic deploy behaviour to the mvn deploy command. See the Build Integration section in the Artifactory documentation.
[DISCLOSURE - I'm associated with JFrog. Artifactory creator.]
Take a look at the deployAtEnd parameter of Maven Deployment plugin: http://maven.apache.org/plugins/maven-deploy-plugin/deploy-mojo.html
This is a bit tricky. Maven is not atomic when it executes the build life-cycle. So a broken set of artifacts may end up in a repository.
One solution I know is Nexus Pro: http://www.sonatype.com/Products/Nexus-Professional/Features - it allows you to promote builds or define certain repos as staging. So only verified versions get promoted to be used. Maybe artifactory has something similar - I just don't know.
If that solution is too expensive you probably need to create a cleanup build or profile to remove artifacts that where already uploaded. My first guess would be to write a Maven plugin to use the the proxy remote API or maybe the maven features are already sufficient. But since deploy means update the meta-data xml files too I dont think there is a delete - not sure on this either.

Maven uses different timestamps when building snapshot artifacts in a large project

We have a large maven 3 project with around 250 modules. All modules have version 1.0-SNAPSHOT and modules tree has single parent module with the same version as a tree root.
Project is built with Bamboo nightly and artifacts are installed to a Nexus repository using command "mvn clean install".
It happens that part of modules are built with one timestamp while the rest with the other, something like:
module1-1.0-20121127.150154-7.jar
module100-1.0-20121127.150527-7.jar
In another project I was trying to set dependency to artifacts of this project using specific version of a snapshot dependency (as discussed in this question Maven specific version of a snapshot dependency) but failed to build due to the problem described above.
Does anyone know why maven would use different timestamps and how to fix that?
MNG-6754 was finally fixed in 3.8.2.

Maven WAR overlay problems, while using Hudson + Artifactory

We have three artifacts:
common.jar : with common classes.
public.war : depending on the common.jar, contains only public site resources.
internal.war : depends on both common.jar and public.war, adding authentication
information and security context resource files. Also contains
few administration site classes.
Currently I have structured these in such way, that internal.war overlays itself with public.war.
Building the project locally, installing the artifacts to local repo, works perfectly.
Problems start when trying to get the Hudson builds working with following sequence:
Build all projects in dependency order.
Modify common.jar (say, add a new class method)
Modify internal.war classes in such way that they are compile-time dependent on changes done in 2. step.
Commit both changes, triggering the Hudson builds.
Internal.war build fails because it can not find the symbols added in step 2.
Somehow the build in step 5. is using an old version of the common.jar, and failing because of it.
The common.jar version number does not change, let's say it's 1.0.0-SNAPSHOT for the purposes of this example.
If I DO change the common.jar version number, the build works. (Supposedly because there is only one release by a release version number).
Now, what could cause this using of old artifacts in Hudson builds?
We are running maven builds on Hudson with command "clean package -e -X -U"
"Deploy artifacts to maven repository" has been checked.
It's hard to definitively answer this without access to the real poms, but here is what I would do:
1) Make sure Hudson is using the exact same version of Maven as you are on your local machine
2) Examine the effective pom.xml of internal.war on the Hudson machine in a terminal via mvn help:effective-pom making sure you are running the same mvn executable as your Hudson job does. You need to verify the version of the common.jar in the effective pom.xml of internal.war. It could be different than what you expect due to profiles or settings.xml differences.
3) Check the settings.xml file for your Hudson install of Maven. In particular you need to verify all is well in your distributionManagement, servers, and repositories stanzas. Another good way to check this is to go to your internal.war project and run mvn help:effective-settings and see if what is there matches what is on your local machine.
Something is awry and it won't take long to find with the right analysis.

Resources