Attaching Build Number for binaries in Maven - maven-2

I am running maven build and storing files in Artifactory. One issue I am facing is when ever I try a -snapshot version it overwrites the binary in Artifactory. I tried using the Maven build number plugin, but running in to issues.I reffered to this
http://blog.codehangover.com/track-every-build-number-with-maven/
Describing below What I did?
Updated the masterpom.xml with following line.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<format>${version}.{0,number}</format>
<items>
<item>buildNumber</item>
</items>
</configuration>
</plugin>
Now I update the pom of ear and webproject as below
<build>
<finalName>${project.artifactId}-${project.version}.${buildNumber}</finalName>
</build>
When I ran mvn clean install, ear and war got generated but when i checked the war inside the ear I am finding it as some thing like war-1.0-SNAPSHOT-null.war. I believe the war and ear couldn't get the buildNumber parameter. I was able to successfully generate the buildNUmber.property files and was able to increment the number by running the buildnumber:create plugin. Here are my questions
What I am doing wrong here and why the buildNumber parameter is not picked.
Also I want to generate all the binaries including jars in the following format binary-version-Snapshot.${buildNumber}. So Do i need to update pom of each file or any other way to update this?
Also we are using Hudson builds for Continous Integration and we want to separate developers builds with Hudson Build number. How can we achieve this if we don't want to checkin the buildNumber.properties after the Hudson build.

To get unique snapshots use the uniqueVersion flag (see James Lorenzen's Blog). If you use the maven goal deploy:deploy-file the uniqueVersion flag is true by default. At my company we have the following policy. Only "official" snapshots go to the repository. A "official" snapshot is one that was build on our reference system (our Jenkins ci server). We don't need the unique feature for snapshots, since we let Jenkins archive the artifacts. This way we can always go back to a certain version if we would like too by using Jenkins. If the build breaks the snapshot will not be deployed to the repo.
To your 2nd question; my understanding is that you need to update every pom file. But since it is a one time change, it shouldn't be too much of a burden.
I am not completely understanding your 3rd question ("... separate developers builds with Hudson Build number..."). In case you want to add the build number for every build done by Hudson, you have several options.
You can add a string as classifier while deploying. Maven will add that classifier in the filename (artifactID-version-classifier.jar - e.g. my.company.calendar-0.0.1-Snapshot-Hudson.jar). The artifact will be retrieved by adding the classifier to the dependency.
add another parameter to your maven call - outputfilename (${project.build.finalName}, see maven docu)
changing your version string to something like

Related

Unable to download the artifact maven-compiler-plugin from repository

I've created a maven project and wanted to change the java compiler version to 1.6 so I added the ff:
<build>
<plugins>
<plugin>
<artifactId>org.apache.maven.plugins</artifactId>
<groupId>maven-compiler-plugin</groupId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
When I run any maven goal in eclipse, it works. But when I run in terminal I got the ff errors:
Project ID: maven-compiler-plugin:org.apache.maven.plugins
Reason: POM 'maven-compiler-plugin:org.apache.maven.plugins' not found in repository: Unable to download the artifact from any repository
maven-compiler-plugin:org.apache.maven.plugins:pom:2.3.2
from the specified remote repositories:
central (http://repo1.maven.org/maven2),
apache.repo (https://repository.apache.org/content/repositories/releases),
jboss.repo.deprecated (https://repository.jboss.org/nexus/content/repositories/deprecated),
Any idea what's causing this issue?
I was able to solved this issue by updating to maven3. But my problem right now is although I specified maven-compiler-plugin version to be 2.4, I'm still seeing 2.3.2 in the log.
Your groupId and artifactId are reversed.
If Eclipse and the command line create different results, then they use different local Maven repositories. The default is in $HOME/.m2/repository/. So the first step is to find out which one (command line or Eclipse) uses a different local cache and why.
The next question is why the download failed. The usual reason is that Maven tried the download and got an error. Maven will remember the error and not try again. To force it to try again, you have to delete the folder $M2_REPO/repository/org/apache/maven/plugins/maven-compiler-plugin/2.3.2/.
Lastly, when you configure 2.4 but see 2.3.2 in the log, then you're either building the wrong project of one of the POMs of your build overwrites the version for the compiler plugin.
To avoid issues like this, use a parent POM where you keep all the versions in dependencyManagement (for dependencies) and pluginManagement (for plugins) elements. That way, you will never have to define a version in a module POM or in other projects which inherit from this one.
After installing maven 3 from a repository and added maven3 home in /etc/environment what I forgot to do is to reboot my machine, after that it worked.
My /etc/environment now looks like:
M3_HOME="/home/edward/java/apache/maven-3.0.4"
MAVEN_HOME="/home/edward/java/apache/maven-3.0.4"
M3="home/edward/java/apache/maven-3.0.4"
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/edward/java/apache/maven-3.0.4"
Here's how I uninstalled and install maven 3:
http://czetsuya-tech.blogspot.com/2012/05/how-to-install-maven-3-in-ubuntu-1110.html

Capturing the Unique Maven SNAPSHOT build number

I am looking for a way to capture the unique SNAPSHOT build number that was generated during the 'mvn deploy' phase of the build. I would like to be able to pass this version (during a Hudson build) to another process used for deploying to an application server. The key here is being able to capture the exact Maven SNAPSHOT build number, such as:
foobar-0.4-20100707.060244-11.war
I have noticed that Hudson is capturing this information if you archive the maven build artifact, but it is not clear how I can expose this variable and pass it to another job (which is what I want to do). I can see this variable in the Hudson Home directory, like so:
/hudson/jobs/JOB_NAME/builds/24/org.ace.widgets$foobar/archive/org.ace.widgets/foobar/0.4-20100707.060244-11
Any Maven and/or Hudson experts out there that have any clue how to expose the SNAPSHOT build number? Hudson is doing it?
Check out my answer to this slightly different problem where I use GMaven to access the project metadata after deploy. What they have in common is that you have to access the unique build number. So you could adapt the script so that after it has read the project meta data (after deploy) it stores the unique version in the maven properties:
pom.properties['uniqueVersion'] = uniqueVersion
If the appserver-deploy-process is also a maven plugin, access this property, otherwise store it as a file using something like this:
new File(pom.build.directory, "uniqueVersion.txt").text = uniqueVersion
Now you can pick it up from target/uniqueVersion.txt using a shell script or so.
A little bit late, but I just noticed that you have exactly the same problem I was facing. I needed to be able to deploy arbitrary build artifacts produced on a Windows box on AIX machines. The deployment process needed to be run locally on the AIX boxes. So I defined slaves on the AIX boxes that download the build artifacts from the build job that run on the Windows box. The master is on the Windows box.
To put it in short. The build job archives the necessary artifacts and triggers the deployment job with its build URL as the parameter (it is actually a "run parameter", but string would work too). The deploy job uses wget to determine the artifact URL (it searches for a artifact ID that contains certain texts, e.g. the artifact name without the version), and downloads the artifact with wget again. wget saves it without version, so that all my deployment scripts can run on the unversioned name. You can use the first step also to find out about the artifact name as well.
wget uses the remote API (xml version). If you don't want to use wget, there is a command line tool that will do the connection for you.
You can test it by appending following strings to the run URL of the build job and use the resulting URL in your webbrowser.
#to find the path (URL) of the artifact
api/xml?xpath=*/artifact[contains(fileName,"MyApp")]/relativePath/text()
#to find the path (URL) of the artifact with more than 1 string to match
#the match must identify exactly one artifact, otherwise you will
#get an error message
api/xml?xpath=*/artifact[contains(fileName,"MyApp") and contains(fileName,".ear")]/relativePath/text()
#To download the artifact
#replace $relativePath with the actual output from one of the queries above
artifact/$relativePath
Based on Sean Patrick Floyds answer, even though this question is old, I'd like to share a full code example which writes the uniqueVersion into a maven property. Please keep in mind that Maven's internals are accessed using reflection, so this may easiliy breaks up in future maven versions. I tested it against Maven 3.2.5.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<executions>
<execution>
<id>set-uniqueVersion-property</id>
<phase>deploy</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
<![CDATA[
def uniqueVersion = null;
println "Grabbing uniqueVersion...";
project.artifact.metadataList.each{
if(it.class.simpleName=='ProjectArtifactMetadata'){
def afi = it.class.superclass.superclass.getDeclaredField('artifact');
afi.accessible = true;
uniqueVersion = it.artifact.version;
}
};
project.properties['uniqueVersion'] = uniqueVersion;
println("Unique Version grabbed: $uniqueVersion");
]]>
</source>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you want to use this property within other maven plugins, please make sure that their executions are made in the deploy phase after the set-uniqueVersion-property execution. If you prefer to write the unique version to a file, simply add
new File(pom.build.directory, "uniqueVersion.txt").text = uniqueVersion
as already stated by Sean Patrick.

using maven to manage java dependencies in a jruby rails app

I'm trying to write a pom.xml that will allow me to run a command locally and fetch all dependencies that my jruby Rails app has. I'm seeing two different configs though and I'm not totally sure which to use (as I'm not a java person whatsoever)
First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)
Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib
So I don't fully understand what the purpose of the first option's dependency list is for. All I want is mvn to copy my jars locally (and then eventually when my CI server does a deploy). Can someone point me in the right direction?
First Option
<project>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
</project>
Second Option
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<configuration>
<artifactItems>
<artifactItem>
<groupId>[ groupId ]</groupId>
<artifactId>[ artifactId ]</artifactId>
<version>[ version ]</version>
<type>[ packaging ]</type>
<classifier> [classifier - optional] </classifier>
<overWrite>[ true or false ]</overWrite>
<outputDirectory>[ output directory ]</outputDirectory>
<destFileName>[ filename ]</destFileName>
</artifactItem>
</artifactItems>
<!-- other configurations here -->
</configuration>
</plugin>
</plugins>
</build>
</project>
First, many Pom's i'm seeing just have a tag under the root of the pom.xml that list all dependencies. This doesn't however have any information about where these are stored etc... so I feel like this isn't what I want (I need to copy them to my rails lib dir)
This is the traditional way to declare and use dependencies on a Java project. Dependencies declared under the <dependencies> element are downloaded from a "remote repository" and installed to your "local repository" (in ~/.m2/repository by default) and artifacts are then handled from there. Maven projects (at least the Java ones) don't use a local lib/ folder for their dependencies.
Second option, I'm seeing in the mvn docs is to use the maven-dependency-plugin, which seems more like what i'm looking for. I assume then that my outputDirectory would be something like lib
The maven dependency plugin allows to interact with artifacts and to copy/unpack them from the local or remote repositories to a specified location. So it can be used to get some dependencies and copy them in lets say a lib/ directory indeed. Actually, it has several goals allowing to do this:
dependency:copy takes a list of artifacts defined in the plugin
configuration section and copies them
to a specified location, renaming them
or stripping the version if desired.
This goal can resolve the artifacts
from remote repositories if they don't
exist in local.
dependency:copy-dependencies takes the list of project direct
dependencies and optionally transitive
dependencies and copies them to a
specified location, stripping the
version if desired. This goal can also
be run from the command line.
The first goal would use the setup you described in your second option. The second goal would use the standard project dependencies that you described in your first option. Both approaches would work.
The problem here is that I don't know exactly what a JRuby Rails app is, what the development workflow is, how to build such an app, etc so I don't know exactly what you need to do and, consequently, what would be the best way to implement that with Maven.
So I googled a bit and found this post that shows another approach based on OS commands (using the maven exec plugin) and has a complete pom.xml doing some other things. Maybe you should look at it and use it as a starting point instead of reinventing everything. This is my suggestion actually.

How can I configure Maven to commit to a Mercurial repository when I install:install

Maven's SCM plug-in doesn't appear to provide a "commit" goal. scm:checkin performs a commit AND push. I need to avoid the push.
I'm simply interested in doing an hg commit during install:install. I'm not using the release plugin and don't need it yet. I'm simply working locally in a multi-module environment and want to ensure that my source repository aligns with my Maven locally-installed snapshots for each module. In other words, every time I install a new snapshot of a module, I want the related code committed to hg to make every snapshot directly correlate to an hg revision (or range of revisions when multiple commits occur between snapshots).
The following will bind scm:checkin to the install phase. As long as the repository is a file:// scheme (at least for Mercurial, according to the code), a push is not performed during scm:checkin.
Define properties used in the following steps:
<properties>
<message>maven install:install auto-checkin.</message>
<repository.local>file:///path/to/local/repository</repository.local>
<repository.type>hg</repository.type>
</properties>
The <message> can be anything you choose. It isn't ideal to be completely fixed as commits should include meaningful messages as to what changes were made. But, I do believe there should be a standard message included in auto-commits to identify it as such. Just modify the <message> property from step 1. before each install.
This is just a standard scm node for a Maven-based project. Since this is concerned only with a local repository, the URLs are all the same.
<scm>
<connection>scm:${repository.type}:${repository.local}</connection>
<developerConnection>scm:${repository.type}:${repository.local}</developerConnection>
<url>scm:${repository.type}:${repository.local}</url>
</scm>
This is plug-in that runs during the install phase that performs the commit. It'll simply execute the proper scm checkin based on the definition in step 2.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>checkin</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
One problem is that I receive the following.
DEPRECATED: Binding aggregator mojos
to lifecycle phases in the POM is
considered dangerous. This feature has
been deprecated. Please adjust your
POM files accordingly.
I'm looking into how to resolve it but, for now, it works and I'm going with it.
What about setting the connectionUrl on the checkin to a throw-away repository on the local box? So your checkout would come from the "central" repo, but your 'checkin' would go only to the working repository (the commit that you want) and the (apparently) unavoidable push would go to file:///tmp/whocares.
Alternately there's probably a single line of code in the scm plugin to comment out to avoid that push.
Maven's scm plugin doesn't appear to provide a "commit" goal. scm:checkin performs a commit AND push. I need to avoid the push.
Then the scm plugin is maybe not what you're looking for :)
I'm simply interested in doing an hg commit during install:install. I'm not using the release plugin and don't need it yet.
To be honest, this is a pretty odd usage. While I understand what you described, it doesn't really make sense to me to "sync" a SNAPSHOT with a revision number. Even if you don't commit code between two SNAPSHOT builds, I don't understand how this can this be a problem. In other words, I don't see what is the added value of forcing the commit. And using the release plugin won't solve anything in my opinion.
To summarize, I don't think that the scm plugin will allow you to achieve your goal (at least not without hacking). I don't know if there is mercurial support in Ant but, if there is, maybe you should look in this direction instead (and use the antrun plugin).

How do you use the maven-simian-plugin in Maven2?

I'm looking for a Maven2 reporting plugin for Simian and the closest thing to such a reporting I found is this. The problem is, the documentation for it appears to be for Maven 1 instead. Why is a Maven 1 plugin stored in a Maven 2 repository? I suppose that means I can use it... but how to use? The site mentions reporting but if I don't have a src/main/site, does that mean I can't use it? I was kinda hoping for something like mvn simian:simian similar to mvn checkstyle:checkstyle and mvn pmd:pmd. I don't want to generate site just for the reports. Sites take too long to generate when all I want is a quite xml report.
The Simian plugin listed on central is actually for Maven 1 (if you inspect the contents you'll see a project.xml and a plugin.jelly). So that explains why it doesn't work. This is rubbish and should be removed in my opinion.
As far as I can make out there isn't a publically available Maven 2 plugin, this may have something to do with the licence (Simian isn't open source).
As an alternative, have a look at PMD's CPD plugin, it may not be as fully featured as simian but I know it works in a Maven 2 build and detects copypasta pretty well.
To configure PMD, add something like the following to your POM:
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</reporting>