Nexus group ordering - maven

We are using nexus as a repository management system. However we are encountering a problem in regards to managing our groups.
Basically we have an snapshot versioned artifact that lives in two repositories. We add both these repositories to the same group in the order that we would like nexus to search them. This is in accordance with the documentation: http://www.sonatype.com/books/nexus-book/reference/config-sect-managing-groups.html
group
...
--> repo1
...
--> com.test.example-1.0.0-SNAPSHOT
...
--> repo2
...
--> com.test.example-1.0.0-SNAPSHOT
...
...
So by ordering repo1 above repo2 we always want to download the example artifact from repo1. What we find in reality however is that despite the ordering, we always download the latest snapshot version from either repo. So if repo2 has a more recent snapshot version we are pulling it down.
Has anyone else seen this behaviour? Does nexus not take ordering into account with snapshot repositories?

This is actually not Nexus but Maven that does it, what happens:
Maven requests "maven-metatadata.xml" from Nexus
Nexus cycles over member repositories in given order (repo1, repo2...) and merges that XML files.
From merged XML, Maven "gets the knowledge" of the latest snapshot, and explicitly asks for it.
Nexus can't do anything, I bet your snapshots has different names (artifactId-1.0-yyyy.mm.dd.hh.mm.jar, but those two has probably different yyymmdd etc), and serves up what Maven asks
What you can do here to make Nexus "hide" stuff from Maven is Routing rules. Add a rule that for given groupId, or artifactId or whatever (it's actually a regexp) serve only from repo1.

Related

Should every application group have their own artifactory release/snapshot repo?

I want to setup Artifactory for a large company and I have a question:
Should every application group have their own set of snapshot and release repos so module collisions don't occur?
The best practice for setting up maven repositories in large companies is to have a SNAPSHOT and a RELEASE maven repo for a functional domain, group of applications or similar.
Probably you need remote repos for external dependencies that are in Maven Central or in other external repositories, in this case, you need to create a remote repo to access these dependencies.
Also, you can have a virtual repo to group all of these local and remote repositories.
For, example:
You have a banking website for personals finances with these maven repos:
SNAPSHOT maven repo: personal-finance-local-SNAPSHOT
RELEASE maven repo: personal-finance-local-RELEASE
You have a banking website for enterprise finances with these maven repos:
SNAPSHOT maven repo: enterprise-finance-local-SNAPSHOT
RELEASE even repo: enterprise-finance-local-RELEASE
If you have external dependencies in Maven Central, you can create two remote maven repos: remote-SNAPSHOT and remote-RELEASE
Finally, create a virtual maven repo in Artifactory to group all maven repos that you want, for example, all of this example. You can have the repo virtual-maven-SNAPSHOT and the virtual-maven-RELEASE where you can have all the SNAPSHOTs or all the RELEASEs dependencies.
If you don't want to have a virtual repo for SNAPSHOTs and another for release versions you can have an unique virtual repo like: virtual-maven
If the company is really that big,(beside the thing you mentioned) it has probably internal release procedures. Like, to be able to release a product even internally some quality assurance protocols must be fullfiled.
In this case, different groups should not able to access other groups repositories without this qa protocols being fullied.
Private repositories for each software group is way to go in this case. And if a group's products can be used internally, It should have another repo for internal releases where others can access.

Maven Nexus: add group repository only with artifacts with prefix xxx.yyy

I wonder if it's possible to define a Group Repository in Maven Nexus and tell it to get the artifacts from existing repositories, but only those with ID matching a certain prefix xxx.yyy
This way, not all the artifacts of a repository will be available at this group repository, but only those I want to publish.
If you are using Nexus 2.x professional, you can use procurement to define a restricted view on a repository, allowing only artifacts that fulfil certain rules. Your intended rule should be among the possible ones.

1.0.0-SNAPSHOT in two Nexus repositories of one group

Say I have a "public" group in Nexus which contains two repositories "snapshotsA" and "snapshotsB". Both contain versions with the same Maven coordinates, like com.something:artifact:1.0.0-SNAPSHOT. How does Nexus resolve a SNAPSHOT reference? Does it look into both repositories to find the latest element? Or is it satisfied after finding the first one?
For groups in Nexus Repository 2.x, we resolve the first match in the group ordering, unless some sort of Repository Routing or Repository Target rules prevent that from being matched (for example if you know bad versions of that component exist in that repository by not treating components immutably, etc...)
In Nexus Repository 3.x this is currently simpler as we have not implemented Repository Routing. The first match in the group ordering is what you would get back.
Group repositories serve a list of repositories under the same URL. They fetch the maven-metadata.xml files from all the repositories they serve and create a merged representation of them. They also have a Lucene index via the maven-indexer (which is a library contributed as OSS by Sonatype to Apache that allows a repository manager, or tool, such as an IDE, to work with this index of artifacts contained in the repository). The index of group repositories is also a merged representation of the indexes of each of the repositories in the group.
As far as I'm aware, for Nexus 2.x, the file system is the first place to try and, if it fails, the Lucene index is queried in order to resolve from the respective proxy repository's remote host.

Migrating maven artifact repositories - pom <url> value points to old repo

Question:
When importing maven artifact repositories (either from other instances of Artifactory, or nexus, for example), many artifacts (and most parent) poms contain url tags which reference the old repository. These url tags are within the distributionManagement and repositories tags.
Do we need to go through a time consuming process of updating these URLs for every single artifact (and parent pom, where applicable)?
Further Information:
We are in the process of migrating some artifact repositories to a whole new environment. We have an old Artifactory instance and a Nexus instance from a separate project that we need to migrate into a single Artifactory instance in a new environment. We currently don't have access to run maven builds from the Nexus repo - we have only been given access to their filesystem to pull artifacts across.
The new Artifactory version is newer than the old one, so we used the following process:
1. system export excluding binaries
2. copy filestore directory across to new Artifactory server
3. imported the system export
For Nexus, we are rsyncing the filesystem for each repository across to the new Artifactory server, and using the 'Import Repository from Path' feature.
These imports have all finished successfully, and we can see all of the required artifacts in the new Artifactory instance.
We have successfully executed a maven build that pulled down dependencies imported from the old Artifactory instance, and this same build successfully published it's artifacts back to the new Artifactory instance as well.
Given our successful tests so far, we're not sure if we really need to update them, or if they will become a problem later for some reason (such as when we decommission the old Artifactory instance)
You're lucky to use Artifactory in your new environment :)
Artifactory will automatically remove any <repositories> references from your pom files, leaving the resolution rules to your settings.xml. All you need to do is generate a new settings.xml file from your new Artifactory and all the resolution will occur from it.
In order for it to work, please declare the old Artifactory and Nexus as remote repositories for the new Artifactory instance (don't use export/import). Once new Artifactory fetches artifact from old Artifactory or Nexus it removes the repositories declaration and stores the new, clean pom in the cache.
After awhile when you sure everything is cached, you can decommission the old servers and declare those repositories as offline (optionally moving the artifacts to local repository).
Neither the repositories nor the distribitionManagement have an impact on your usage of the components and as such nothing needs to be done on the import.
The distributionManagement details where components are released to. Since the component are already released and in your repo server the content does not matter.
Having repositories as an element in your pom files is a very bad practice and should be avoided. However if you are using a repo manager and the appropriate settings using the mirrorOf setup in settings.xml none of the repositories will be taken into account, but instead your repo manager will be contacted as defined in your settings.xml.
As you can see you can just migrate the components and leave them alone. Modifying the poms of already released components is probably a bad practice, since it means that some clients will have one pom, while others will have a different one for the SAME artifact. This violates the idea of a non-changing release artifact and can cause problems.
And in terms of migration you can easily just migrate the repositories in Nexus and turn off the old servers (at least you could migrating to Nexus). That way you don't have to run a number of them in parallel and can quickly decommission, while at the same time being sure you have all your components in your new repo manager.

Maven repository inheritance and override

I have a Maven project that was built a few years back, and now I need to make some updates. One of the dependencies to my project has a Maven repository listed in its POM that no longer exists. I get build failures now.
I would have thought the repository listings in my POM or Settings.xml would trump any repositories listed in a dependency's POM; or Maven would try my repositories after failing to connect to the extinct repository. Instead, it just bombs out with a build failure.
Additionally, I already have the required dependencies in my local repository. I would have additionally thought that Maven would just use that.
Is there a way to override the inherited repository listings, or tell Maven to carry-on in the case of a repo problem?
If the artifact that you depend on is a snapshot version then maven will check for a new snapshot every time you build, thats why it is a good practice to lock down your dependencies to a released version.
You can "override" the repository declarations by defining a <mirror> in the settings.xml.
See http://maven.apache.org/settings.html#Mirrors
I usually set up a locally hosted repository manager (preferably nexus) and then define mirrorOf(*) = local-repo-manager/url.
Nexus allows multiple repo's to be grouped with a predefined search order.
Nexus repo's can be locally hosted or caching/proxies to public repo's.
I usually have a locally hosted 3rd party repo at the front of the group, where I can store artifacts that are not published on public repo's.

Resources