IntelliJ IDEA 13 doesn't recognize Maven mirrors - maven

I have a Maven project with a mirror set up for central repo, like that:
<settings>
...
<mirrors>
<mirror>
<id>central-my</id>
<mirrorOf>central</mirrorOf>
<name>Maven Central Repo mirror</name>
<url>http://local_url:15999/nexus/content/repositories/central/</url>
</mirror>
</mirrors>
...
</settings>
For some reason, when I import this project into IDEA and make it use this settings.xml it still doesn't see this mirror, showing me http://repo.maven.apache.org/maven2 instead (Project Settings > Maven > Repositories). The problem is, I can't update from this repo because I'm on internal network. What can I do in this case?

Using mirrorOf is discouraged, since it defeats the idea of having separate repositories for promotions (e.g. from snapshots to staging to releases), access control etc. This feature exists in Maven since the time there was no proper Binary Repository with multiple repositories support in the market, so Maven developers lived in the world where one proxy exposed one URL for all the remote repositories it proxied. That's, of course, no longer true.
Another usage of this setting was to ensure your in-house repository is not shortcut by repositories declarations in dependencies' pom files, but there are better solutions for this problem as well.
All in all, don't use mirrorOf. Instead, you should "shadow" the central and plugins repositories, replacing them with your in-house repository URL.
Here's an example of settings.xml for Artifactory (should be similar for Nexus):
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<profiles>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>libs-releases</name>
<url>http://jbaruch.artifactoryonline.com/jbaruch/libs-releases</url>
</repository>
<repository>
<snapshots />
<id>snapshots</id>
<name>remote-snapshot-repos</name>
<url>http://jbaruch.artifactoryonline.com/jbaruch/remote-snapshot-repos</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>plugins-releases</name>
<url>http://jbaruch.artifactoryonline.com/jbaruch/plugins-releases</url>
</pluginRepository>
<pluginRepository>
<snapshots />
<id>snapshots</id>
<name>plugins-snapshots</name>
<url>http://jbaruch.artifactoryonline.com/jbaruch/plugins-snapshots</url>
</pluginRepository>
</pluginRepositories>
<id>artifactory</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>

Related

How to get all remote repositories of a maven project hierarchy?

I'm redirecting all maven repository access to an Artifactory with the following ~/.m2/settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- unclear what version changes -> use 1.1.0 because it's higher -->
<servers>
<server>
<id>central</id>
<username>admin</username>
</server>
<server>
<id>snapshots</id>
<username>admin</username>
</server>
</servers>
<mirrors>
<mirror>
<id>artifactory</id>
<name>artifactory</name>
<mirrorOf>*</mirrorOf>
<url>https://[hostname]:[port]/artifactory/remote-repos/</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>artifactory</id>
<repositories>
<repository>
<id>central</id>
<name>remote-repos</name>
<url>https://[hostname]:[port]/artifactory/remote-repos</url>
<snapshots>
<enabled>false</enabled>
<updatePolicy>interval:25200</updatePolicy>
</snapshots>
</repository>
<repository>
<id>snapshots</id>
<name>remote-repos</name>
<url>https://[hostname]:[port]/artifactory/remote-repos</url>
<snapshots />
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<name>remote-repos</name>
<url>https://[hostname]:[port]/artifactory/remote-repos</url>
<snapshots>
<enabled>false</enabled>
<updatePolicy>interval:25200</updatePolicy>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>snapshots</id>
<name>remote-repos</name>
<url>https://[hostname]:[port]/artifactory/remote-repos</url>
<snapshots />
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>
and thus have to add extra remote repositories which are specified by a project (and its child projects) to the Artifactory instance. I currently use
find . -name pom.xml -exec grep -B 5 -C 5 '<repository>' {} +
which isn't very handy in case an URL is a variable and declared elsewhere and it doesn't skip duplicates. It's not the worst thing in the world, but maybe there's an improvement available.
The following doesn't work:
mvn versions:display-dependency-updates doesn't display remote repositories
mvn dependency:list-repositories only works until the first dependency can't be fetched if the proxy is enabled so that I have to figure out where to get it from, add the researched remote repository to Artifactory or move ~/.m2/settings.xml aside - less handy than the find command above
The solution should work recursively, i.e. include all repositories in all child projects and childrens child projects, etc.
It makes a lot of sense that a solutions don't require to download the dependencies directly from the remote repository first without the proxy since I'd like to transfer them through the Maven proxy immediately if possible - it's not a requirement, though.
A somewhat hacky approach could be those two steps:
Get the effective POMs. Note that the below goal generates an XML file containing all POMs at once. However, variable names will already be resolved.
mvn help:effective-pom -Doutput="effective-pom.xml"
Parse the resulting XML file and gather the repositories, e.g., using a Python script gather-repos.py.
#!/usr/bin/python
import sys, xml.etree.ElementTree as ET
root = ET.parse('effective-pom.xml').getroot()
repositories = dict()
for node in root.iter('{http://maven.apache.org/POM/4.0.0}repository'):
repo_id = node.findtext('{http://maven.apache.org/POM/4.0.0}id')
repositories[repo_id] = node
for node in repositories.itervalues():
ET.ElementTree(node).write(sys.stdout, default_namespace='http://maven.apache.org/POM/4.0.0')
Of course, the script can then be run via
chmod +x gather-repos.py
./gather-repos.py

Configure jcenter for only downloading artifacts and Artifactory for deploying artifacts

We have Artifactory setup and we use Maven central repo for downloading artifacts, which are then automatically cached in Artifactory. We also upload/deploy our own artifacts in Artifactory.
I now want to replace Maven central repo with jcenter and would like to continue using our Artifactory for uploading/deploying our own artifacts and for also caching the jcenter (and any third-party) artifacts. I can ask all developers to modify their settings.xml file as it will be a one-time activity so that's not a problem.
I saw this link by #helmedeiros which describes making changes in <repositories> and <pluginRepositories> section of settings.xml file. However, those are the sections where i specify URL for our Artifactory server. If i replace my Artifactory URL, then it would mean that i will be able to both fetch and upload artifacts from jcenter which is not what i want.
How can i ensure that all developers are only able to pull (NOT deploy/upload) from jcenter and deploy/upload ONLY to Artifactory?
Here's what we have right now in settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd" xmlns="http://maven.apache.org/SETTINGS/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<servers>
<server>
<username>${security.getCurrentUsername()}</username>
<password>${security.getEscapedEncryptedPassword()!"*** Insert encrypted password here ***"}</password>
<id>central</id>
</server>
<server>
<username>${security.getCurrentUsername()}</username>
<password>${security.getEscapedEncryptedPassword()!"*** Insert encrypted password here ***"}</password>
<id>snapshots</id>
</server>
</servers>
<profiles>
<profile>
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>libs-release</name>
<url>https://inhouse-artifactory/artifactory/libs-release</url>
</repository>
<repository>
<snapshots />
<id>snapshots</id>
<name>libs-snapshot</name>
<url>https://inhouse-artifactory/artifactory/libs-snapshot</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>plugins-release</name>
<url>https://inhouse-artifactory/artifactory/plugins-release</url>
</pluginRepository>
<pluginRepository>
<snapshots />
<id>snapshots</id>
<name>plugins-snapshot</name>
<url>https://inhouse-artifactory/artifactory/plugins-snapshot</url>
</pluginRepository>
</pluginRepositories>
<id>artifactory</id>
</profile>
</profiles>
<activeProfiles>
<activeProfile>artifactory</activeProfile>
</activeProfiles>
</settings>
I will really appreciate any help in this regard.
I have exactly the same question :)
My solution is to create an Artifactory virtual repository (forgerock-third-party-virtual) to cache most of the public artifacts.
This virtual repository includes a remote repository based on jcenter:
On the virtual repository, there is no default deployment repository:
So with this setting, I hope the developers won't be able to push in this virtual repository.
According to the JFrog documentation, you have select one repository in this drop-down to be able to push into a virtual repository.
Regarding the deployment settings, we also have a parent pom where we specified our own repositories in the <distributionManagement> section.
On my build machines, I've added this profile (in .m2/settings.xml) to cache the artifacts:
<profile>
<id>force-third-party-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>forgerock-third-party</id>
<name>ForgeRock Third Party Repository</name>
<url>http://maven.forgerock.org/repo/forgerock-third-party-virtual</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>forgerock-third-party</id>
<name>ForgeRock Third Party Repository</name>
<url>http://maven.forgerock.org/repo/forgerock-third-party-virtual</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</profile>
I have other settings in this file to declare our own Artifactory repositories (for pushing/pulling our own artifacts) + some Maven credentials.
I did some tests with one of our Maven projects and it was working fine.
Once the new .m2/settings.xml will be ready, I'll push a template in an internal Artifactory repository, so the developers will be able to get this template with a curl command.
FYI, this is a POC for the moment. We want to move in production with these settings in a few days.

How to use Sonatype Nexus as a mirror for Ivy dependencies [duplicate]

This question already has answers here:
Use public maven repository with ivy
(3 answers)
Closed 7 years ago.
Id like to use Sonatype Nexus as a company-internal maven/ivy repository. My goal is that every request goes to nexus, and if nexus does not (yet) contain the requested artifact, it should delegate the request to the official maven repository. All artifacts that were downloaded from the official maven repository should be saved on nexus (as a backup). In addition, I want to be able to save my own artifacts the server for other project to use them (e.g. internal libraries)
In a past project, we have set up a Sonatype Nexus server to be used as a mirror for the maven repository which worked fine. Now I'm struggeling with an project which uses Ivy to accomplish the same with the existing nexus installation.
In the maven project, we had the following in settings.xml
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<interactiveMode />
<usePluginRegistry />
<offline />
<pluginGroups />
<servers>
<server>
<id>deployment</id>
<username>[USERNAME]</username>
<password>[PASSWORD]</password>
</server>
</servers>
<mirrors>
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://mavenserver:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<!--Enable snapshots for the built in central repo to direct -->
<!--all requests to nexus via the mirror -->
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<!--make the profile active all the time -->
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
How can I accomplish the same with Ivy?
As long as you are using Ivy to access Maven repositories and not some custom defined Ivy format you can use the approach documented in the Nexus Repository Manager documentation.
Also check out the examples project for a working example.
And if you are using Ant you can also use Eclipse Aether instead of Ivy. More to that also in the docs and examples.

maven - multiple repository lookup configuration

I'm using maven v3.0.1 for my projects. I've projects which depends on artifacts from a corporate remote repository. Also I had a local archiva repository in company which hold local artifacts, which are not in to corporate remote repository.
I would like to make the settings.xml in such a way that for all projects, it will lookup for the specified artifact first in the corporate remote repository, if not found there, look up for the artifact in the local archiva repository.
I added local repository in <repository> tag and enabled the profile for that <activeProfile>. But the looking up is not happening as expected. On analysis found that mirrorOf setting plays a role there. Following are my settings.xml.
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://corporate-repo:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
<repository>
<id>spring-snapshot</id>
<name>Spring Maven SNAPSHOT Repository</name>
<url>http://repo.springsource.org/libs-snapshot</url>
</repository>
<repository>
<id>internal</id>
<name>Local Release Repository</name>
<url>http://local-repo:8081/repository/internal</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>nexus</activeProfile>
</activeProfiles>
</settings>
How can I modify the settings.xml to do the lookup as I required ? Whether any way to provide two urls in the mirrorOf settings. I tried
<mirror>
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://corporate-repo:8081/nexus/content/groups/public,http://local-repo:8081/repository/internal</url>
</mirror>
No errors in xml parsing, but lookup is not working. Can any one shed light on how to resolve this issue
I experimented with lot of options and finally resolved by tweaking the mirrorOf settings to <mirrorOf>*,!internal</mirrorOf>
So mirror settings are,
<mirrors>
<mirror>
<id>nexus</id>
<mirrorOf>*,!internal</mirrorOf>
<url>http://corporate-repo:8081/nexus/content/groups/public</url>
</mirror>
</mirrors>
* ensures that for all request except internal repo !internal do lookup in corporate repo. For internal repo, do look up in local-repo configured with repository id as internal

Maven archetype catalog : specify custom location(s)

I'm deploying a Nexus repository for Maven, and custom archetypes on it.
I would like to execute mvn archetype:generate and be prompted a list of internal + custom archetypes.
The only way I found to prompt custom archetypes (in an ergonomic way, meaning no URL) is to define the archetype-catalog path as a property in the settings. This is not a valid solution because I want several catalogs (and this property cannot be overriden in CLI).
Does anybody have a clue on how to do that ?
Thanks in advance,
[EDIT]
I found an issue report related : http://jira.codehaus.org/browse/ARCHETYPE-273
And I noticed that during archetype:generate, maven tries to reach the central repository :
[DEBUG] Searching for remote catalog: http://repo1.maven.org/maven2/archetype-catalog.xml
[DEBUG] Searching for remote catalog: http://repo1.maven.org/maven2
It ends by a "Connection Timed out" because I did not (and don't want to) specify a proxy...
I don't understand why maven doesn't check nexus catalog...
I also have a Nexus configured to mirror the Maven repositories and thus the remote catalog too.
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://afbwt03:8081/nexus/content/groups/JavaRepo/</url>
</mirror>
and:
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
I am able to access the remote catalog only when I use the following Maven command line:
mvn archetype:generate -DarchetypeCatalog=http://afbwt03:8081/nexus/content/groups/JavaRepo
If I don't define the archetypeCatalog variable, I get the same behavior as you do: trying to access the repo1. ... although some mirrors are configured.
You need to have
the property archetypeRepository defined in the active profile in your .m2/settings.xml
the repositories and pluginRepositories redirected to your mirror, on the same id "central".
and of course, the mirror defined
Apache maven documentation on archetype plugin specifies that archetypeRepository is definable user property:
http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html
Your .m2/settings.xml should have these minimal elements
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<mirror>
<id>central</id>
<name>Mirror for maven central</name>
<url>http://mymvnhost:8081/nexus/content/groups/public/</url>
<mirrorOf>*</mirrorOf>
</mirror>
</mirrors>
<profiles>
<profile>
<id>dev</id>
<properties>
<archetypeRepository>http://mymvnhost:8081/nexus/content/groups/public/</archetypeRepository>
</properties>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>http://central</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>dev</activeProfile>
</activeProfiles>
</settings>
With maven-archetype-plugin:3.1.1 you have to
add/edit archetype-catalog.xml on your repo to list your custom archetypes
edit your settings.xml to add this repo with id archetype.
invoke mvn archetype:generate -DarchetypeCatalog=remote
From https://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html :
If you want the catalogs to come from a different repository, please add the following to your settings.xml
<repository>
<id>archetype</id>
<url>https://repository.domain.com/path/to/repo/</url>
</repository>

Resources