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

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.

Related

Reg upload to artifactory

We maintain an artifactory within our intranet which is used by the development team.
When ever any new dependency is added to any project , we upload the new jars into artifactory.
This is currently a tedious process and we are trying to find if there is any simple way out.
The current process is - if a project defines a new dependency , we need to connect to internet and build the project using gradle so that we get to know what are the new dependencies ( we in fact track the logs what are the dependant and transitive dependant jars which are getting downloaded fresh )
Then we create a zip of these new jars alone and upload to artifactory. This is time consuming and error prone as well
Is there any better way to achieve this ? When i build using gradle connecting to internet , is it possible to publish the new dependencies as well to maven local repo or to some new folder so that we can zip that folder alone and upload to artifactory ?
Kindly revert if anybody has a simple solution for the above problem.
This is a maven answer but the same will apply to gradle.
You should be able to define a virtual repository in your artifactory, which is a combination of the local (artifactory hosted) and the maven central repo (internet hosted).
Your maven/gardle users will configure the virtual repository (not the internet) in their settings.xml, then when a dependency is loaded maven will look in repostories in the following order:
1) local user repo at ~/.m2/repo
2) artifactory local repository
3) maven central
Each time a new artifact is loaded from 3 (no one has ever asked for it before) it will be added to 2 and 1, so the next user who calls for that dependency will only ever go as far as 2.
See https://www.jfrog.com/confluence/display/RTF/Virtual+Repositories

Where to actually put internal repository URL?

I see several options:
directly in pom.xml
in company super-pom
in settings.xml (global or user)
in a profile or directly (in settings.xml or pom.xml)
We want our Jenkins to push artifacts to internal repository, and developers to pull missing artifacts from there.
If I put the repository URL in pom.xml, and later the internal repository is moved to a different address, the released versions will all have a broken link.
Super-pom saves some repetition, but in a clean setup you need to somehow know where the repository is to find the parent POM — to tell you where the repository is.
Having the URL in settings allows one to change it without modifying the artifacts, but there are two problems:
build will fail due to unresolved dependencies, if maven settings have no reference to the internal repo
developers have to update their settings.xml files manually
I'm also unsure about the merits of putting repository configuration in profiles. I know it let's you easily switch the repositories on and off, but shouldn't the -o option and snapshot resolution settings be enough for most uses?
What about using a different repository (e.g. with instrumented classes) for integration tests?
Configure a single repository in the users ${HOME}/.m2/settings.xml and configure other needed repositories in your appropriate repository manager either Nexus, Artifactory or Archiva. In Jenkins there is the Config File Provider plugin which exactly handles such situations in a very convinient way.
If you want to have repeatable builds and good control over your organization internally, use a repository manager and use a mirrorOf entry in everyone’s settings.xml to point at that url.
If you are exposing your source and want to make it easy for others to
build, then consider adding a repository entry to your POM, but don’t
pick a URL lightly, think long-term, and use a URL that will always be
under your control.
http://blog.sonatype.com/2009/02/why-putting-repositories-in-your-poms-is-a-bad-idea/

Can Sonatype Nexus use maven's local repository

I now have a PC working as a Sonatype Nexus server and a development environment. I know Nexus stores artifacts for proxy type repository in SonatypRoot\sonatype-work\nexus\storage, and Maven will use a local repository to store artifacts (default directory is C:\USERS\USER_NAME\.m2\repository).
So the question comes when I'm using Maven with Nexus running on the same machine, because i have two copies of every artifact which is big waste of storage.
In Nexus's configuration tab for proxy type repository, there is an option named Override Local Storage Location.
My question is can I set this to my Maven's local repository?
That's a bad idea. One common purpose of nexus to publish artifact internally within your organisation. Typically this is done using mvn deploy. On the other hand your maven local repository serves purpose as a cache to avoid downloading stuff that has been obtained before. If you mix them together you might be accidentally publishing artifacts to your organisation while you just want to test locally in your PC.

Reusing Artifactory's maven repo

I'm trying to figure out if its possible to reuse Artifactory's maven repo on the local machine where the Artifactory server is running. The following details what I am trying to do.
I have a server where Artifactory runs and I'm planning on setting up Jenkins on the same server. If possible, I would like to have only one maven repository on the server. Since Artifactory already runs there, I would expect it is maintaining some kind of a maven repository (I looked around for it but couldn't find it).
Currently, when Jenkins uses Maven to build a maven project, it downloads the dependent jars into a local maven repo (a .m2 folder) on the server. Instead of this, would it be possible to point the settings.xml that maven is using to some local folder under Artifactory where artifactory stores all the jars? Basically, I would like maven to think that all the jars are already available in a local repo (which artifactory is maintaining) and so it wouldnt have to download all the jars from artifactory.
If maven and artifactory can share the same repo folder, this would be possible. But if Artifactory uses its own strucuture to maintain the maven repository (something other than the structure maven follows with its .m2 folder) this would not be possible.
I should state that I have very minimal knowledge of Artifactory, other than the fact that it is a maven repository manager.
Answering my own question here, as more research suggests that this is not possible. I found another question here on SO that states:
Artifactory uses Java Content Repository (JCR) standard to store artifacts. It is an abstraction above various storage implementations, which include filesystem, relational databases, etc. In any case, JCR manages the store by checksums (to reduce size and bandwith), so the repository is not directly browesable in the filesystem. The default implementation is storing the binaries on the filesystem (inside $ARTIFACTORY_HOME/data/filestore and the metadata in Derby DB.
How Artifactory manages repos
A blog post by the Nexus guys also suggests that this is not possible.
Contrasting Nexus and Artifactory -> Contrast #2

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