What is Mirror in Maven settings.xml file? - maven

Correct me if I'm wrong, but a Mirror is used to redirect all traffic to a specific repository URL and block everything else (including Maven central repo).
Now what if I have a Mirror to http://a.com:8081 and a repository to http://b.com:8081. Would the second URL ever get used? I assume the answer is a No. Can you have multiple Mirrors?

Correct me if I'm wrong, but a Mirror is used to redirect all traffic to a specific repository URL and block everything else (including Maven central repo).
This is not entirely correct. Artifacts are downloaded by Maven by searching them inside defined repositories. Those repositories are defined in project's POM or in the Maven settings. But, as specified in the Mirror documentation:
However, you may want to use an alternative mirror for a particular repository without changing the project files.
Let's take the example from the documentation and comment on it:
<mirrors>
<mirror>
<id>UK</id>
<name>UK Central</name>
<url>http://uk.maven.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
This defines a single mirror that will be used when Maven will want to fetch a dependency from the Maven Central Repository. Let's say you have 2 current repositories, which are Maven Central and a custom repo A. What happens is the following:
You are declaring a dependency to an artifact;
Maven will look for that dependency inside your defined repositories, so it will look for it inside the repository A and Maven Central;
Let's say it starts with A: it will hit the URL defined for that repository, like you would expect. Then let's say it wasn't found there;
It will then look inside Maven Central. However, Maven will notice that a mirror was configured for that repository. It will not hit Maven Central at repo1.maven.org. Instead, it will fetch it from uk.maven.org, which is the URL defined in the mirror configuration element.
As this example shows, a mirror only applies to certain repositories, which are defined with the <mirrorOf> configuration element. In the previous case, we had <mirrorOf>central</mirrorOf> which means "Mirror Maven Central". This element can have various values, and the documentation gives examples:
Examples:
* = everything
external:* = everything not on the localhost and not file based.
repo,repo1 = repo or repo1
*,!repo1 = everything except repo1:
Now what if I have a Mirror to http://a.com:8081 and a repository to http://b.com:8081. Would the second URL ever get used? I assume the answer is a No.
The above shows that the answer is not strictly no. The mirror to http://a.com:8081 will be used when Maven will try to fetch a dependency from one of the repository that it mirrors. If it indeed mirrors the repository to http://b.com:8081 then no requests will ever be made to http://b.com:8081 (they will be redirected to http://a.com:8081); but if it doesn't, Maven will continue to fetch dependencies from http://b.com:8081 like usual.
Can you have multiple Mirrors?
Yes, you can.

To answer your questions:
Correct me if I'm wrong, but a Mirror is used to redirect all traffic to a specific repository URL and block everything else (including Maven central repo).
Kind of right, but I would say all artifacts are redirected to the mirror.
The blocking doesn't happen because it's a mirror. The filtering or re-direction happens based on what is defined in the <mirrorOf> element.
The syntax <mirrofOf>*</mirrorOf> causes ALL repositories to be directed to that mirror. To use your words, the mirror blocks the other repository http://b.com:8081. (but I wouldn't use those words).
If, however, you defined the mirror pattern as:
<mirrofOf>*,!third-party-repo</mirrorOf>
then the mirror would handle all artifacts that were not found in the other repositories. So in this case (in your words), the mirror would not block access to the other repositories.
Now what if I have a Mirror to http://a.com:8081 and a repository to http://b.com:8081. Would the second URL ever get used? I assume the answer is a No.
This all depends on how you've defined your mirror and repositories as explained above, it is possible for them both to be used.
Can you have multiple Mirrors?
Yes. The maven docs explain how to do that here: https://maven.apache.org/guides/mini/guide-mirror-settings.html#advanced-mirror-specification
But I've never personally had the need to deal with multiple mirrors. Instead, I typically have one mirror and then one or more repos.
I'll explain that next.
Example using a mirror and two repos
In this example, I have:
One public mirror of Maven central (called acme-central) for my fictitious company Acme.
One repo for my companies locally developed artifacts (called acme-repo).
One repo for a 3rd party company third-party-repo that has some artifacts I needed (called third-party-repo).
The simplified syntax for all of this is shown below. I'm only showing the bits of the configuration that affect this example.
<settings>
<mirrors>
<mirror>
<mirrorOf>central,!acme-repo,!third-party-repo</mirrorOf>
<profiles>
<profile>
<id>default</id>
<repositories>
<repository>
<id>acme-repo</id>
<url>https://acme.com/repository/releases</url>
<repository>
<id>third-party-repo</id>
<url>https://third-party.com/repository/releases</url>
<activeProfiles>
<activeProfile>default</activeProfile>
So we have a mirror (of maven central), and two other repositories.
The mirror statement says to use the mirror instead of maven central, but not for the two repos acme-repo and third-party-repo.
The profile is required (just because that is the syntax of the settings.xml file). You can only define <repositories> within a profile.
The repositories have names, and the way artifacts are looked up is as follows (see Repository Order in Maven docs). What follows is simplified for this answer.
settings.xml file is used
pom.xml file is used
Before downloading from a repository, mirrors configuration is applied.
The maven docs show an example with two <mirror>s.
Running the command mvn help:effective-pom -Dverbose is a good way to see which repo/mirror was used to download an artifact because the syntax is:
Downloading from third-party-repo: https://third-party.com/...
Downloading from acme-repo: https://third-party.com/...

Related

How to make Maven deploy using a different, ad-hoc group Id?

Some background:
I have copied the master branch of an external github repository, not owned by me, into a personal repository
This repo contains a Java project and uses Maven for building and compilation
The group ID defined in all pom.xml files is org.mylibrary (let's assume)
When deploying to Artifactory, the deployment is done to myrepo/org/mylibrary/...
I'd like to deploy instead to:
myrepo/org/myorganization/mylibrary
but I would like to avoid editing all the pom.xml files, and replacing all lines containing:
<groupId>org.mylibrary</groupId>
with:
<groupId>org.myorganization.mylibrary</groupId>.
I'm configuring the deployment via the distributionManagement element:
<distributionManagement>
<repository>
<name>releases</name>
<id>deployment.credentials</id>
<url>https://artifactory.lab.myorg.org/artifactory/myrepo</url>
</repository>
</distributionManagement>
What's a clean way of solving this? Replacing the groupId definition in all pom.xml files does the trick, but, as said, that's something I want to avoid.
Thanks!
When deploying to any repository, Artifactory utilizes the layout that is configured for this repository. By default, for Maven repositories, Artifactory uses the "maven-default" layout.
I would recommend you to first add your requested layout and then configure your repository with the newly created layout.
I hope this information is found helpful.

How to publish all jar for an existing project in a nexus/sonartype?

I have a maven project, and I have already all my dependencies in my local host. I want to push all these dependencies into nexus/sonartype.
I don't want to push my jar one by one by uploading via nexus interface.
So I copied the content of my maven repository ($MAVEN_HOME/repository) into {nexus-data}/storage/public
Nexus have to recalculate index after restarting?
You might want to use Distribution Management -
<distributionManagement>
<repository>
<id>some-artifactory</id>
<name>Artifactory Name</name>
<url>http://your.artifactory.address/releases</url>
</repository>
<snapshotRepository>
<id>other-artifactory</id>
<name>Other Artifactory Name</name>
<url>http://your.artifactory.address/snapshots</url>
</snapshotRepository>
</distributionManagement>
Repository
Where as the repositories element specifies in the POM the location
and manner in which Maven may download remote artifacts for use by the
current project, distributionManagement specifies where (and how) this
project will get to a remote repository when it is deployed. The
repository elements will be used for snapshot distribution if the
snapshotRepository is not defined.
So I copied the content of my maven repository ($MAVEN_HOME/repository) into {nexus-data}/storage/public
Don't do that. In Nexus 3, Nexus doesn't use raw files so relying on this approach isn't going to work for you anyway.
You should be using distribution management as described by #nullpointer. If you can't for some reason, you could write a script to use Nexus' REST API to upload many artifacts. That's more useful when you aren't building using Maven. For example, maybe you have a whole pile of legacy jar files to upload.

How to Change Maven repository to inbuilt repository in same network

In our project we need to setup a repository in a remote machine and I need to point to that repository. I have tried changing settings.xml.
But that didn't work. Then I added repository directly in pom.
This works. But still I am seeing the artifacts are downloaded from central repository. When I checked the effective pom, I am seeing that central repository is been mentioned along with mentioned internal repository
I dont need artifacts to be downloaded from central repository. Instead I need to download from my remote repository. How can I achieve it. TIA :)
You can force Maven to use a single repository by having it mirror all repository requests. The repository must contain all of the desired artifacts, or be able to proxy the requests to other repositories. This setting is most useful when using an internal company repository with the Maven Repository Manager to proxy external requests.
To achieve this, set mirrorOf to *.
<settings>
...
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Maven Repository Manager running on repo.mycompany.com</name>
<url>http://repo.mycompany.com/proxy</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>
more details here

How can I force maven to resolve a variable's literal value in the pom it is used in?

It seems that Maven doesn't resolve variables until they are used in the child pom. This means that variables inherited from a parent like ${basedir} are incorrect when used by the child. For example, I have:
<repositories>
<repository>
<id>lib</id>
<url>file://${basedir}/mavenrepo</url>
</repository>
</repositories>
in my parent pom (because I'm using jars that haven't been pushed to any maven repo and I don't want to host my own).
I have a directory called 'mavenrepo' in my project root. However, when a child attempts to resolve this repo, the variable ${basedir} now points to the child project's directory and not the parent's base dir.
How can I force maven to resolve the ${basedir} to point to the directory that contains the parent pom?
The best i can suggest is to use a repository manager like Artifactory, Nexus or Archiva. Nexus has a very simple setup and makes life easier in particular if you have artiacts which not available via Central or other repositories.
In this relationship i can recommend to read Stephen Connolly blog about such kind of problem.
Apart from i would recommend to use Stephen Connolly's non-maven-jar-maven-plugin which should help in such situations.

Difference between using a single repository and a single mirror

The maven documentation says:
http://maven.apache.org/guides/mini/guide-mirror-settings.html
Using A Single Repository. You can force Maven to use a single
repository by having it mirror all repository requests. The repository
must contain all of the desired artifacts, or be able to proxy the
requests to other repositories. This setting is most useful when using
an internal company repository with the Maven Repository Manager to
proxy external requests.
To achieve this, set mirrorOf to *.
<settings>
...
<mirrors>
<mirror>
<id>internal-repository</id>
<name>Maven Repository Manager running on repo.mycompany.com</name>
<url>http://repo.mycompany.com/proxy</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>
I don't understand this paragraph.
Shouldn't it be something like this?
Using A Single Mirror You can force Maven to use a single
mirror by having it mirror all repository requests. The mirror must contain all of the desired artifacts for all the
repositories, or be able to proxy the requests to other
repositories. This setting is most useful when using an internal
company repository with the Maven Repository Manager to proxy external
requests. To achieve this, set mirrorOf to *.
<settings>
...
<mirrors>
<mirror>
<id>internal-mirror</id>
<name>Maven Mirror Manager running on mirror.mycompany.com</name>
<url>http://mirror.mycompany.com/proxy</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
...
</settings>
Where is my miss-understanding?
I mean, <mirror><id>internal-repository</id>... seems just wrong to me.
Mirror means a repository that is used as a passerelle/proxy to an other repository.
When using a repository manager like Nexus, Artiafactory, Archiva... you dispose of one local entreprise repository wich proxifies remotes ones.
So there is no need to declare too many repositories in your pom or setting.xml. Using Just one mirror which redirect all requests to the repository manager you have will be sufficient.
That is the meaning of the documentation.
As maven documentation says:
Repositories can be declared inside a project, which means that if you have your own custom repositories, those sharing your project easily get the right settings out of the box. However, you may want to use an alternative mirror for a particular repository without changing the project files.
For repositories in settings.xml, declaring mirrors for them is redundant because you can just replace the repositories directly. You should use mirrors for repositories in pom.xml.
For example. Project X is a public project that list all the repos it required in its pom.xml.
Most people can just download and build the project directly.
Alex wants to build the project on his working PC at company, and his company has an internal enterprice repo. So he uses the company repo in his settings.xml as a mirror for the project repos.
Bob cannot access some project repos directly due to connection issue. He can use other public mirrors for that repo.
Repos in pom.xml is used as default implements and mirrors should be used for special cases.

Resources