Maven automatic SNAPSHOT update - maven-2

Let's say I have one project with the following POM:
<groupId>com.mine</groupId>
<artifactId>coreJar</artifactId>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
And then in another project I always want to reference the latest SNAPSHOT:
<dependencies>
<dependency>
<groupId>com.mine</groupId>
<artifactId>coreJar</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
...
<dependencies>
But instead of 0.0.1-SNAPSHOT, I want it to always grab the latest SNAPSHOT version. In the past you could use LATEST, but this has since been deprecated (for reasonable reasons).
I do understand you can specify versions, such as:
[1.5,)
But I could never get it to work with a "-SNAPSHOT":
[0.0.1,)-SNAPSHOT // Doesn't work!
The question then is how do I get maven to grab the latest SNAPSHOT in my other project?

Another option (which I use) is to include the following in your pom.xml. updatePolicy tag will force maven to always use latest snapshot from this repo.
<repositories>
<repository>
<id>you-snapshots</id>
<url>http://host/nexus/repos/snapshots</url>
<snapshots>
<updatePolicy>always</updatePolicy>
</snapshots>
<releases>
<updatePolicy>always</updatePolicy>
</releases>
</repository>
</repositories>
p.s. I always configure all repos in pom.xml because we use several CI servers and it will be quite hard to configure all of them (I am lazy...)
Doc on settings.xml updatePolicy for reference.
The frequency for downloading updates - can be "always", "daily" (default), "interval:XXX" (in minutes) or "never" (only if it doesn't exist locally).

Use
mvn -U, --update-snapshots
Forces a check for updated releases and snapshots on remote repository

A few words about dependency ranges and SNAPSHOT dependencies (quoting the Dependency Mediation and Conflict Resolution design document):
Incorporating SNAPSHOT versions into the specification
Resolution of dependency ranges should not resolve to a snapshot (development version) unless it is included as an explicit boundary. There is no need to compile against development code unless you are explicitly using a new feature, under which the snapshot will become the lower bound of your version specification. As releases are considered newer than the snapshot they belong to, they will be chosen over an old snapshot if found.
So, to answer your question, the only way to use a SNAPSHOT with dependency ranges is as boundary and you won't get higher SNAPSHOT versions automatically by design (which really makes sense).
Personally, I don't like to use dependency ranges because I find that it can lead to build reproducibility issues and makes the build more fragile. I do not recommend them.
Just in case, upgrading the SNAPSHOT version typically means that you are releasing some code and the maven release plugin provides support for that (see the Updating POM Versions).

There is a Versions plugin for Maven which allows you to update your pom to the latest greatest SNAPSHOTS in visible repositories. It does this by inspecting your pom and comparing against remote repositories and then modifying as required.
It is a useful tool but I would definitely like to see an equivalent to the deprecated LATEST option. I find this kind of dependency particularly useful in continuous integration scenarios.

use mvn install -U
u must use this to force maven to get the latest snapshots

It's
<version>[0.0-SNAPSHOT,)</version>

In case you want to update your SNAPSHOT releases inside Eclipse (when using m2e / m2eclipse), right click the affected project, then select "Maven" -> "Update Project..." -> "OK" (with selected project causing problems).

Related

how to download the pdfbox-app jar?

I'm working with pdfbox-app-2.0.0-20140226.103319-176.jar. But i notice there is a continues development and Apache PDFBox application published new version frequently. In the officials’ side I can see pdfbox-app-2.0.0-**-182,183,184.jar in the following URL. I try to get with the pdfbox-app-2.0.0-**-177,178,179,180,181.jars using pom.xml file, but no luck. Could you please help me to get pdfbox-app-2.0.0-**-177,178,179,180,181.jars.
Could you please help me to get pdfbox-app-2.0.0-**-177,178,179,180,181.jars.
No, no one could (except in the case the source repository were tagged for every snapshot, or you are so lucky to find somebody who have saved that specific version).
You should work with public repository, but if you need a not yet published functionality you could work with snapshot repository. In such a case you have to be aware you are using an unstable, rapidly-evolving, version so if your program works today it might not work tomorrow because the code has evolved: in general this "problem" is a wanted behavior when working with unstable versions.
In fact that problem notifies you that you are counting on a functionality that will not exists in the future at the same way as it existed in your used (old) version, and the earlier you discover the error the better your are able to change your work without too much pain.
In order to work with a snapshot repository add (in your case):
<project>
<modelVersion>4.0.0</modelVersion>
<repositories>
<repository>
<id>ApacheSnapshot</id>
<name>Apache Repository</name>
<url>https://repository.apache.org/content/groups/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
then add the dependency:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-app</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
More generally speaking working effectively with SNAPSHOT is to be intended in the context of a development process where developer teams communicate and project managers are in charge of making deadlines respected.

Accessing Java BigQuery Tools in Maven with Nexus

I'm at the very beginning of building a bigquery uploader in Java. Goal is to download a full twitter stream and uploading that into hourly buckets, then processing these in Dremel for a topic detection and tracking project. This is all Java on MacOSX in Eclipse Juno, plus Maven with a local Nexus proxy.
I'm stuck at the starting gate; finding and compiling a simple Java sample that authenticates and uploads a CSV file. Closest I've found is bigquery-appengine-sample, although I don't see why I need appengine for a bigquery project. Will explore that later.
Problem is, the project won't build in maven. No error flags shown in eclipse, but often eclipse error flags are unreliable. The pom shows a red eclipse flag on this element:
com.google.apis
google-api-services-bigquery
${bigquery.version}
Maven install fails with
[ERROR] Failed to execute goal on project bigquery-appengine-sample: Could not resolve dependencies for project com.google.api.client:bigquery-appengi
ne-sample:war:1.0.0-SNAPSHOT: The following artifacts could not be resolved: com.google.apis-samples:shared-sample-appengine:jar:1.3.2, com.google.api
s:google-api-services-bigquery:jar:v2-rev18-1.7.2-beta: Failure to find com.google.apis-samples:shared-sample-appengine:jar:1.3.2 in ...SOF won't allow URLs... was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed
or updates are forced -> [Help 1]
Nexus proxies are defined for http://mavenrepo.google-api-java-client.googlecode.com/hg/ and http://google-gson.googlecode.com/svn/mavenrepo/ (both set as SNAPSHOT). Neither of these seem seem to be working. Browse storage and indexes both come up empty (just an archetype catalog). However Browse Remote does seem to work AFAICT; shows a maven repository tree that seems complete.
So my question: how to build bigquery samples in Java with maven?
There's a few non-App Engine Java samples here: http://code.google.com/p/google-bigquery-tools/source/browse/samples/java/
I use Sonatype's Maven plugin, and at minimum, your pom.xml should look like 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.google</groupId>
<artifactId>google</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>google</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.10.3-beta</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-bigquery</artifactId>
<version>v2-rev19-1.7.2-beta</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client</artifactId>
<version>1.8.0-beta</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>google-api-services</id>
<url>http://mavenrepo.google-api-java-client.googlecode.com/hg</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
Based on what I can observe from outside google, the answer to the question as posed is:
No java example is available (yet?) that covers uploading. The sample
at the address in the posted answer only covers querying sample data
that is already present in the account.
The closest sample to what I need seems to be the
command line and python samples. But using them is complicated by the fact that
each sample is hard-wired
to work only with specific maven dependency versions, samples aren't being updated
when new API versions are released, and older API versions are often not available via
maven.
The maven problem seems to originate from using a wildly idiosyncratic version
numbering system (such as the v2beta1-rev17-1.7.1-beta-beta example
above). Maven relies on strict adherence to convention, and such
version numbers definitely don't comply. For rapidly changing
beta code, version numbers should be major#.minor#.micro-SNAPSHOT as documented in the maven book. NO EXCEPTIONS or maven breaks as explained in the comments.
URGENT REQUEST: Please provide a working java sample that covers all BigQuery features, particularly step 1; uploading data. Please bundle the samples with the API code to ensure they stay in sync. And adopt maven conventions throughout, including retroactively.
I was able to get this to work after testing out the url http://google-api-client-libraries.appspot.com/mavenrepo for these libraries. It does not allow browsing so nexus will attempt to index this repo and fail. When this happens Nexus blocks access to this repo and thus local build fails due to missing dependencies.
To alleviate this I changed two settings in Nexus for this repository.
Download Remote Indexes = false
AutoBlock Enabled = false
With this set I was able to build and download dependencies correctly.
Note: We also use GCM-Server Repo for Android and it had this same issue, the same solution was applied and we were able to cache the new dependency.

Question about maven

Why is maven downloading dependencies from repository even if the jar exists on my local repository(one reason could be that jar doesn't have a pom), is there a way to get bypass that except with the -o option?
Why is maven downloading [SNAPSHOT] dependencies from repository even if the jar exists on my local repository
Because that's the expected behavior with SNASPSHOT dependencies. Unlike fixed versions, Maven will periodically try to download the most recent version of a given SNAPSHOT. That's extremely useful when you're depending on a project that is under active development. From the Maven Reference:
3.3.1.2. SNAPSHOT Versions
Maven versions can contain a string
literal to signify that a project is
currently under active development. If
a version contains the string
“SNAPSHOT,” then Maven will expand
this token to a date and time value
converted to UTC (Coordinated
Universal Time) when you install or
release this component. For example,
if your project has a version of
“1.0-SNAPSHOT” and you deploy this
project’s artifacts to a Maven
repository, Maven would expand this
version to “1.0-20080207-230803-1” if
you were to deploy a release at 11:08
PM on February 7th, 2008 UTC. In other
words, when you deploy a snapshot, you
are not making a release of a software
component; you are releasing a
snapshot of a component at a specific
time.
Why would you use this? SNAPSHOT
versions are used for projects under
active development. If your project
depends on a software component that
is under active development, you can
depend on a SNAPSHOT release, and
Maven will periodically attempt to
download the latest snapshot from a
repository when you run a build.
Similarly, if the next release of your
system is going to have a version
"1.4", your project would have a
version "1.4-SNAPSHOT" until it was
formally released.
As a default setting, Maven will not
check for SNAPSHOT releases on remote
repositories. To depend on SNAPSHOT
releases, users must explicitly enable
the ability to download snapshots
using a repository or pluginRepository
element in the POM.
When releasing a project, you should
resolve all dependencies on SNAPSHOT
versions to dependencies on released
versions. If a project depends on a
SNAPSHOT, it is not stable as the
dependencies may change over time.
Artifacts published to non-snapshot
Maven repositories such as
http://repo1.maven.org/maven2 cannot
depend on SNAPSHOT versions, as
Maven's Super POM has snapshot's
disabled from the Central repository.
SNAPSHOT versions are for development
only.
If you really want to change this behavior, you can change the updatePolicy of your snapshot enabled repository:
<repositories>
<repository>
<id>my-repo</id>
<name>My Corporate Repository</name>
<url>http://repo.mycompany.com/maven2</url>
<layout>default</layout>
...
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
Switching to never will force you to use a manual update (using mvn -U). But beware, this is usually not what people want and expect with SNAPSHOTs.
For the record, Maven 3 has a -nsu, --no-snapshot-updates command line option allowing to Suppress SNAPSHOT updates.
See also
3.2. The POM
Repositories in the POM reference
You could generate a pom in your local repository by installing the file manually:
mvn install:install-file
-Dfile=[FILE]
-DgroupId=[GROUP]
-DartifactId=[ARTIFACT]
-Dversion=[VERSION]
-Dpackaging=jar
-DgeneratePom=true
-DcreateChecksum=true
EDIT: You wouldn't want to do this for snapshots.

Specify artifact version outside of pom

Is there a way to specify the artifact version outside of the POM file?
I have 2 CI projects that build an artifact. One builds a "stable" development version from a 'develop' branch and the other builds an unstable version which is the result of merging all active feature branches into the develop branch. I want the stable version to build as xyz-1.0.jar and the integration build to go in as xyz-1.0-SNAPSHOT.jar. Is there a way for the CI job to run a maven task or specify via the command line if a release or snapshot jar should be built without manually modifying the POM? Currently I have the version specified as 1.0 in the pom. I considered using the release plugin but I don't want the automatic version number increase and tagging that it does.
Short answer: no. And here are some additional remarks:
It doesn't make much sense to use a "released" version (i.e. non SNAPSHOT) for a branch under CI since released versions are not downloaded again even if a newer version is available.
Released versions should be tagged (e.g. 1.0), maintenance is done is in a branch derived from the tag (e.g. 1.0.1-SNAPSHOT).
If you want to distinguish versions built from different branches, use different versions in the POMs.
I was able to accomplish this by using a property in my POM and then overriding it via the command line.
pom.xml:
...
<version>${artifactVersion}</version>
<properties>
<artifactVersion>1.0</artifactVersion> <!-- default version -->
</properties>
...
Then overriding with mvn -DartifactVersion=1.0-SNAPSHOT package
But Pascal's answer above is more in line with what I was really asking. My solution is more of a workaround I feel.
You should be able to achieve this using maven profiles

To download jar file to local .m2 repository using settings.xml

I have a remote repository which updates the jar once in 5 hours without changing the version number.Pom file is not able to update as the version is same.Each time I need to manually delete.Is there any way i can get the latest files using the settings.xml.
Do you control this remote repository? If yes, then use a "-SNAPSHOT" version number.
Or ask the people who do control the repository to do that. It's the correct way to tell Maven that the dependency is in a state of flux.
And if you're unable/unwilling to do that, write yourself a batch/shell script to invoke Maven, which deletes the file beforehand.
I have a remote repository which updates the jar once in 5 hours without changing the version number. Pom file is not able to update as the version is same. Each time I need to manually delete. Is there any way i can get the latest files using the settings.xml.
No, there is no way to achieve this. Once an artifact with a fixed version (as opposed to SNAPSHOT) has been downloaded, it won't be downloaded again, unless you remove it from your local repository. Actually, re-releasing a jar without changing its fixed version number is an EVIL practice and must be avoided. This is just not how maven works and when doing this, it's impossible to predict which version people are really using (without asking them to explicitly remove the jar from their local repository which is a very weak practice) and this will lead to unpredictable results.
The right way to handle frequent releases is either to change the version number (and updating POMs accordingly) or to use a SNAPSHOT version which is the common approach used during development. By definition, SNAPSHOT version will be downloaded if a newer version is made available in the remote repository. This is what you are looking for and this is the maven way to manage this situation. For more details about SNAPSHOT, see the chapter 9.3.1.2. SNAPSHOT Versions of Maven: The Definitive Guide.
You can set element updatePolicy to always for a repository in your settings.xml:
<profiles>
<profile>
<id>default</id>
<repositories>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
<id>snapshots.jboss.org</id>
<name>Snapshot JBoss Repository for Maven</name>
<url>http://snapshots.jboss.org/maven2/</url>
<layout>default</layout>
</repository>
</repositories>
</profile>
</profiles>