Latest nexus release artifact - maven-2

I have setup a Nexus repository to store our built artifacts, third party dependencies, and home brewed shared source code headers.
I am currently using wget to retrieve the third party dependencies and shared source headers for use while building our software applications (the source for the specific applications are stored in separate git repositories).
When you use wget, you essentially have to know the exact version of the artifact that you want - you must explicitly know what the latest version number is.
Is there another way to retrieve the latest version of an artifact from the maven releases nexus repository without actually knowing what the version number is?
It would be ideal if there was a way to do this using wget instead of maven itself because I don't want to force users to install apache maven just for the purpose of downloading artifacts from nexus.

I think you cannot do it by using curl only. You will need to accomplish other tasks to achieve what you want.
Here is a possibility:
You should first access to maven repository metadata file. (You will find the documentation here: http://maven.apache.org/ref/3-LATEST/maven-repository-metadata/repository-metadata.html)
For instance, let's say that you want to download the latest version of the following maven artifact from maven central:
groupId = javax
artifactId = javaee-api
Download the following file:
http://central.maven.org/maven2/javax/javaee-api/maven-metadata.xml
Its contents will be something like:
<metadata>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<versioning>
<latest>8.0</latest>
<release>8.0</release>
<versions>
<version>7.0</version>
<version>8.0</version>
</versions>
<lastUpdated>20170915063942</lastUpdated>
</versioning>
</metadata>
Then you will need to access the latest tag to retrieve the latest version.
Documentation says the following regarding the meaning of the latest or release tag:
latest String What the latest version in the directory is, including snapshots
release String What the latest version in the directory is, of the releases only
You should find this file also in nexus repositories, and you should use something like xmllint to obtain the value you want. For instance:
curl http://central.maven.org/maven2/jx/javaee-api/maven-metadata.xml \
| xmllint --xpath "/metadata/versioning/latest/text()" -
or
curl http://central.maven.org/maven2/jx/javaee-api/maven-metadata.xml \
| xmllint --xpath "/metadata/versioning/release/text()" -
depending on what you want exactly.
After that, you can use the version information to compose the full URL of the artifact you want to download.
Hope this helps.
Cheers.
Edu.

Related

Why does maven use my internal repository before my local repository?

when I am doing development I often need to change a dependency, but I'm not ready to deploy my changes. For example, I'm working on project Foo and I realize I need to add a method to the common library. Before deploying this change to our internal repository, I would like to install the changes to common library (mvn install) and recompile Foo to use the common library in the local repository (note that I'm using all SNAPSHOT versions).
However, after I mvn install my common library, when I recompile Foo it doesn't use the new common library--it keeps using the latest SNAPSHOT of common library in the internal repository. If I deploy the changed common library, Foo picks it up immediately.
How can I get maven to look first in the local repository?
UPDATE: when the file is installed into the local repository, it gets a name like foo-1.0.0-SNAPSHOT.jar, but when I deploy it, it gets a timestamp foo-1.0.0-20111104.191316-23.jar. I think this is why the remote artifact gets pulled each time. Any idea why mvn install is not working like mvn deploy? Does it have to do with the fact that I have a snapshot repository set up for deploy?
By default, Maven checks for new versions of SNAPSHOT artifacts once per day. When it does this check, it will download SNAPSHOTS from remote repos that are newer than what you have locally. Either your artifact timestamps are out of sync and you're doing something to override Maven's update policy (like calling it with -U or setting the udpatePolicy to "always"), or else the local repository you're installing the artifact to isn't the same one you're subsequently running Maven against. What you're describing isn't typical Maven behavior. For a better answer, give more details in your question.
One indicator you can look for: after you install your common artifact, when you next compile Foo, does Maven download the common artifact again? If so, then it really is getting it from the remote, and you need to check your update settings. If not, then you have something strange going on locally.
You can try this option. This worked for me.
In your project's main pom.xml change 'snapshots' enabled setting to 'false'.
<repository>
<id>yourRepo</id>
<name>Repository</name>
<url>http://your.repo.com/repo</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>

Maven command to install remote dependency locally

I have a base pom which defines repository locations for the nexus we are running behind our firewall and all of our projects inherit from this base pom. However the base exists in one of the repositories defined in the base, so you can see the circular reference problem. I'd like a maven install:install-file like command I can have new team members run in order to pull down and install the base project locally without having to check the project out from source control and mvn install it.
I'd like a maven install:install-file like command I can have new team members run in order to pull down and install the base project locally without having to check the project out from source control and mvn install it.
The Maven Dependency Plugin and its dependency:get goal might help here, you could do something like this:
mvn org.apache.maven.plugins:maven-dependency-plugin:2.1:get \
-Dartifact=groupId:artifactId:version[:packaging] \
-DrepoUrl=http://repository.mycompany.com/
But let me come back on the following:
However the base exists in one of the repositories defined in the base (...)
Unless this is really what you want (adding a repository for thing not found in central), this is usually not how people declare a Nexus repository in a corporate environment.
People usually want all requests to go though their Nexus repository and store artifacts in it. Storing all the artifacts you need yourself is the only way to be sure that you'll be able to repeat your build in 1, 5, 10 years. Sure, the maven folks are doing a great job with central but are you sure you want to rely on something not under your control? So people usually declare Nexus as a mirror of everything (check the section 4.2. Configuring Maven to Use a Single Nexus Group) in the settings.xml.
And if you don't want every user to add the required snippet in their ~/.m2/settings.xml, the best option is to distribute and use a corporate version of the Maven client and to preconfigure it as required using the conf/settings.xml file.
References
Nexus User Guide
Chapter 4. Configuring Maven to Use Nexus

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

Don't download artifact from remote repository

I'd like to specify some artifacts that SHOULD NOT be downloaded from a remote repository, even if they are present there. Is there any way to achieve this in maven2?
Have you tried the offline mode?
mvn -o
Not sure if this is what you need, but you can declare a dependency with system scope, which tells Maven that a particular JAR is assumed to be in the classpath (e.g. one that is included in the java installation directory).
From the docs:
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.
AFAIK, Maven treats the local repository basically as a cache of a remote repository, so there isn't any way to tell it not to get a particular dependency from a remote repo.
I'm not clear exactly what you're after, so here's answers to a few different interpretations:
If the artifacts are transitive dependencies, you can specify that the dependencies be excluded. See the Transitive Dependency Exclusion section of the Dependency Mechanism documentation.
If you want to make sure no artifacts are downloaded, you can set Maven to offline mode by passing -o as a command line switch, or adding <offline>true</offline> to your settings.xml
With the Nexus Maven repository manager, you can set up a proxy repository to the remote repository, and configure the proxy to block certain artifacts. You would do this by adding a "repository target" matching the artifact's groupId and artifactId, then create read permissions for the that target that the Nexus user doesn't have. Any user connecting to the proxy would then not be able to obtain that artifact. See the Nexus book for details, of configuring targets.
If none of these meet your needs can you elaborate on your question please.
One option would be to install a local copy of the file with the install-file mojo and give your copy a distinct name. Pre-pending "local." to the groupid name would make it easy to id in the pom files. If would also make it easy to switch out.
add it to your local repos like this:
mvn install:install-file -Durl=file://xmlthing.jar -Dinternal -Dfile=xmthing.jar -DgroupId=local.org.xmltool -DartifactId=xmlthing -Dversion=1.6.1 -Dpackaging=jar
You would then replace
<dependency>
<groupId>org.xmltool</groupId>
<artifactId>xmlthing</artifactId>
<version>1.6.1</version>
</dependency>
with
<dependency>
<groupId>local.org.xmltool</groupId>
<artifactId>xmlthing</artifactId>
<version>1.6.1</version>
</dependency>

How do I find out Apache Buildr/Maven 2 repo names

I'm just starting to use Apache Buildr and I'm constantly running into the problem of not knowing what repo urls and versions are available for me to use.
For example I want to use Scala 2.8 in a build file, the id i previously used was:
2.8.0-SNAPSHOT
But now this is not found. I also want to use the latest version of Apache POI. If I look on the maven2 repo:
http://mirrors.ibiblio.org/maven2/
I can see that it only has up to version 3.2.
Is there any standard way of finding repos and searching them for what they have available?
Is there any standard way of finding repos and searching them for what they have available?
No, there is no directory of repositories (actually, having many repositories kinda defeats the concept of a central and unique repository but I guess that centralizing everything is a bit utopia).
But there are several repository search engines that index the most "famous" one (like central, java.net, codehaus, jboss):
http://repository.apache.org/
http://www.artifact-repository.org/
http://mvnrepository.com/
http://www.mvnbrowser.com/
http://www.jarvana.com/
http://mavensearch.net/
http://maven.ozacc.com/
http://www.mavenreposearch.com/
http://www.mvnsearch.org/
http://repository.sonatype.org/
In the particular case of Apache POI, version 3.6 is available in the central repo. To use it, just declare the following dependency:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
To search the repositories try NetBeans. It provides a nice repository browser, where you can add the repositories which you like.
Here are some (see Pascal's for more):
http://download.java.net/maven/2/ ('java.net')
http://repository.jboss.com/maven2/ ('jboss.org')
http://bits.netbeans.org/maven2/
http://repo1.maven.org/eclipse
NetBeans also provides autocompletion within the pom.xml for dependencies etc (e.g. to get the latest version) ... but for scala I am not sure if this is useful.