Maven unable to download from remote repository - maven

I'm trying to build a Maven module that depends on SVNKit.
So my pom.xml looks like this:
<dependencies>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>tmatesoft-releases</id>
<url>http://maven.tmatesoft.com/content/repositories/releases/</url>
</repository>
</repositories>
When I try to do a mvn clean install, it looks like it attemps to look into a Nexus repository, and obviously cannot find it. I'm obviously trying to download the artifact from a remote repository at: http://maven.tmatesoft.com/content/repositories/releases
I took a look at my settings.xml file in my ~/.m2/ folder and I see that there is a mirror that looks like this:
<mirror>
<!--This sends everything else to /public -->
<id>nexus</id>
<mirrorOf>*</mirrorOf>
<url>http://Our_Nexus_Repository</url>
</mirror>
I thought that, if you define a <reposotiry> tag, your module's pom.xml will take precedence over what's defined in your settings.xml file.
Any help is appreciated. Thank you.

this is because the mirror will mirror all the repositories, : <mirrorOf>*</mirrorOf>
you can change replace it like this : <mirrorOf>*,!tmatesoft-releases</mirrorOf>
more info please visit : http://maven.apache.org/guides/mini/guide-mirror-settings.html

With the way that you're using the mirror statement in your settings.xml, you're directing maven to always go to your repository. If that is indeed the behavior that you wish, you should create a proxy for the tmatesoft-releases repository inside your nexus installation.
A common methodology for doing this is to setup a repository group for all releases you wish to have on your nexus installation. Then just add proxy repos to the group as needed, and users won't need to change their settings.xml to instantly have visibility to the new repos you add.

Related

Why are settings.xml and pom.xml are not directing Maven to deploy to Artifactory?

I am trying to point Maven to a local Artifactory (OSS) repo (both on my Mac) so I can build code provided by a vendor. I have created an empty Maven local repo and virtual repo in Artifactory, and can use Generate Settings to create the snippets. My ID and encrypted password seem to be working OK in ~/.m2/settings.xml
I have updated the code's pom.xml file and that seems to be causing Maven to resolve from Artifactory.
No matter how I configure in ~/.m2/settings.xml or in the master settings.xml or with -Dmaven.repo.local, Maven wants to deploy to a disk path to the local repo.
If I specify a partial path, Maven says "Using local repository at " a path consisting of the code's home + the path I said.
If I specify a path starting with a / (root), Maven says "Using local repository at /whatever"
I want to specify "https://localhost/artifactory/reponame" so Maven will deploy there. Artifactory generates snippets that contain that kind of URL. But since a URL doesn't start with a /, Maven insists on prepending the code home location to the URL, which of course is nonsense.
There must be some combo of and or <distributionManagement> <repository> <id>central</id> <name> <url>https://localhost/artifactory/... that makes this work. What am I missing?
pom.xml snippet:
<distributionManagement>
<repository>
<id>central</id>
<name>LocalMac-releases</name>
<url>https://localhost/artifactory/TBX</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>LocalMac-snapshots</name>
<url>https://localhost/artifactory/TBX</url>
</snapshotRepository>
</distributionManagement>
Master settings.xml snippet: localRepository is commented out so it takes the default. When commented in whatever I enter does take effect... combined with ${user.home}.
<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->

Repository mirroring

I'm starting with maven and is not all clear what to put in mirror <mirrorOf></mirrorOf> tag.
What I understood:
1> * means "everything"
2> ! prepended to a name exclude that name from look-up path
3> central is used whan mirroring maven central
Now what I want to do is to mirror a repository that is not maven central (teamdev's one in my case), hence I have no idea towards what the field should match: com.teamdev, jxbrowser or com.teamdev.jxbrowser
this is what is listed on temadev website as maven repo:
<repository>
<id>com.teamdev</id>
<url>https://europe-maven.pkg.dev/jxbrowser/releases</url>
</repository>
and
<dependency>
<groupId>com.teamdev.jxbrowser</groupId>
<artifactId>jxbrowser-cross-platform</artifactId>
<version>7.21.2</version>
<type>pom</type>
</dependency>
Each artifact stored in some maven remote repository, and to have it as dependency we should include this repository definition to the project pom.xml.
Most artifacts available in Central repository and it's defined per each pom.xml by super-pom.
com.teamdev
On this page
temadev website mentioned, that in order to use this dependency:
<dependency>
<groupId>com.teamdev.jxbrowser</groupId>
<artifactId>jxbrowser-cross-platform</artifactId>
<version>7.21.2</version>
<type>pom</type>
</dependency>
you have to add
<repository>
<id>com.teamdev</id>
<url>https://europe-maven.pkg.dev/jxbrowser/releases</url>
</repository>
to your pom.xml <repositories>...</repositories>.
Adding a mirror
And if you want to specify another location (artifacts download url) for com.teamdev repository-id, you may specify it in your pom.xml without mirroring.
But if your dependency contains some <repository> and downloads transitive dependencies from it, you have to add a mirror to specify another url.
in your settings.xml file add:
<settings>
...
<mirrors>
<mirror>
<id>com.teamdev-mirror</id>
<name>com.teamdev Mirror Repository</name>
<url>https://your-repository-url</url>
<mirrorOf>com.teamdev</mirrorOf>
</mirror>
</mirrors>
...
</settings>
is not all clear what to put in mirror tag
<mirrorOf>com.teamdev</mirrorOf> matches the <id>com.teamdev</id> in repository definition.
And this artifact jxbrowser-cross-platform should be available in your https://your-repository-url mirror with all other dependencies from the original repository.
And you have to refer your settings.xml file when run maven commands, e.g. if settings.xml present in the project root:
mvn clean compile -s settings.xml
or see more about settings reference here.

How to disable maven blocking external HTTP repositories?

Maven blocks external HTTP repositories by default since version 3.8.1 (see https://maven.apache.org/docs/3.8.1/release-notes.html)
Is there a way to disable that or to exempt a repository from this rule?
I found a solution to do this by inspecting the commit in the Maven git repository that is responsible for the default HTTP blocking: https://github.com/apache/maven/commit/907d53ad3264718f66ff15e1363d76b07dd0c05f
My solution is as follows:
In the Maven settings (located in ${maven.home}/conf/settings.xml or ${user.home}/.m2/settings.xml), the following entry must be removed:
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
</mirror>
If you work in a project and cannot make sure the Maven settings are always like that, e.g. because you share code with other people or want to use CI/CD with automated testing, you may do the following: Add a directory named .mvn in the project. In the .mvn directory, add a file named maven.config with the content --settings ./.mvn/local-settings.xml. In the .mvn directory, add a file named local-settings.xml. This file should look like this:
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://........</url>
</mirror>
</mirrors>
</settings>
Where inside the <mirrorOf> tag, you need to specify the id of the blocked repository, and in the <url> tag, you specify the original url of the repository again. You need to create this unblocker mirror for every repository you have that is blocked.
Example:
If you have the following HTTP repositories defined in the pom.xml:
<repositories>
<repository>
<snapshots>
<enabled>false</enabled>
</snapshots>
<id>central</id>
<name>libs-release</name>
<url>http://my-url/libs-release</url>
</repository>
<repository>
<id>snapshots</id>
<name>libs-snapshot</name>
<url>http://my-url/libs-snapshot</url>
</repository>
</repositories>
Then you need in the .mvn/local-settings.xml:
<settings>
<mirrors>
<mirror>
<id>release-http-unblocker</id>
<mirrorOf>central</mirrorOf>
<name></name>
<url>http://my-url/libs-release</url>
</mirror>
<mirror>
<id>snapshot-http-unblocker</id>
<mirrorOf>snapshots</mirrorOf>
<name></name>
<url>http://my-url/libs-snapshot</url>
</mirror>
</mirrors>
</settings>
I hope my work can help other people who stumble upon this. However, if you have a more elegant or better solution, please share!
In my case, I just added a dummy mirror with the id maven-default-http-blocker to override the existing one. This disable HTTP blocking for all repositories.
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>dummy</mirrorOf>
<name>Dummy mirror to override default blocking mirror that blocks http</name>
<url>http://0.0.0.0/</url>
</mirror>
</mirrors>
</settings>
Another possible solution/workaround is to override the new default http-blocking behavior by commenting out the maven-default-http-blocker mirror in the <mirrors> section of the maven's 'main' settings.xml file (under /opt/maven/conf in my case);
<!--mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror-->
P.S. Whether unblocking all the insucure http repositories is a good idea is a whole other story.
You should just add a mirror to your http repository that allows http in your maven settings. You shouldn't eliminate the default maven behavior for all repositories. Then tell your devops team to use https!
in .m2/settings.xml:
<mirrors>
<mirror>
<id>my-repo-mirror</id>
<name>My Repo HTTP Mirror</name>
<url>http://url-to.my/repo</url>
<mirrorOf>my-repo</mirrorOf>
</mirror>
</mirrors>
In macOS Monterey, and using Intellij Ultimate 2021.3 (and up), with maven NOT INSTALLED in the system and using maven as a plugin inside Intellij, i found the "settings.xml" file in the path:
${user.home}/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/213.5744.223/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml
Note: the above path is when the Intellij is installed using the Jetbrains Toolbox App, and the version number indicated (213.5744.223) can defer if you have another version, verify when travelling the path to the file.
Open the "settings.xml" file with your favourite editor, and comment the next lines:
<!--<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>-->
Hope it helped.
I solved the issue by simply replacing "http" with "https" in .xml file (in my case pom.xml).
This solved my error.
Unblock a Specific HTTP Repository
To unblock a specific repository, you may define a dummy mirror of it in your settings by adding a <mirror> with the same url, and its <mirrorOf> value matching your repository's id. Nothing else needs to change for this to work.
For example:
If your repo id is team-internal-repo, then a mirror added to your ~/.m2/settings.xml might look like this:
<settings>
...
<!-- Add a mirror. -->
<mirrors>
<mirror>
<id>team-internal-repo-mirror</id>
<mirrorOf>team-internal-repo</mirrorOf> <!-- Must match repository id. -->
<name>Dummy mirror to unblock the team repo server</name>
<url>http://insecure-internal-server/repository/team-repo/</url>
<!-- <blocked>false</blocked> --> <!-- This is not needed, the mirror is unblocked by default. -->
</mirror>
</mirrors>
<!-- Existing profile does not need to change. -->
<profiles>
<profile>
<id>default_profile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>team-internal-repo</id>
<name>Dev Team Internal Artifacts</name>
<url>http://insecure-internal-server/repository/team-repo/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
...
</profile>
</profiles>
</settings>
The <blocked> tag is not needed here. Other users have commented that the tag breaks older versions of maven. I tested an http repo with and without this tag and it worked both ways. (Tested using maven 3.8.2.)
Unblocking one or more explicit repos is better than universally unblocking all http repositories. Doing that may be a bad idea:
It presents a greater security risk. There's a reason apache made this change, and it is discussed in the release notes referenced by OP: https://maven.apache.org/docs/3.8.1/release-notes.html#cve-2021-26291
Modifying the internal configuration of your Maven installation (i.e. the settings file in /opt/apache-maven-3.8.1 instead of your own in ~/.m2) could create a headache when updating or reinstalling future releases of maven. If that file gets overridden, your repo might suddenly be blocked again.
Same problem with macOS Monterey 12.3.1 and IntelliJ 2022.1 using bundled maven (3.8.1). The solution is similar to the one proposed by MrBitwise but the settings file has a different path (it is the one embedded inside the app contents folder):
/Applications/IntelliJ\ IDEA\ CE.app/Contents/plugins/maven/lib/maven3/conf/settings.xml
Then I commented the following code:
<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>true</blocked>
</mirror>
You could follow the official recommendation from the Maven documentation, it is explained in the same link that you shared: https://maven.apache.org/docs/3.8.1/release-notes.html#how-to-fix-when-i-get-a-http-repository-blocked
Options to fix are:
upgrade the dependency version to a newer version that replaced the
obsolete HTTP repository URL with a HTTPS one,
keep the dependency version but define a mirror in your settings.
It includes a link to Maven - Guide to Mirror Settings
As others mentioned, you should not override the default security settings.
Sometimes, when your local version of settings.xml is low and your maven version is higher than that, then removing this configuration cannot solve the problem:
<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://........</url>
</mirror>
Maybe see if adding <blocked>false</blocked> will solve the problem:
<mirrors>
<mirror>
<id>my-repository-http-unblocker</id>
<mirrorOf>my-blocked-http-repository</mirrorOf>
<name></name>
<url>http://your blocked url</url>
<blocked>false</blocked>
</mirror>
</mirrors>
Use the latest versions of your dependencies and plugins. I had the same issue with libraries from 'com.sun.xml.ws', but changing their versions from 3.8.3 to 4.0.0 fixed it.
If you are using maven version 3.8 or greater HTTP is not supported. Try to use a lower version or upgrade the repo to HTTPS For more information please refer
https://help.mulesoft.com/s/article/Maven-error-when-building-application-Blocked-Mirror-for-repositories#:~:text=Upgrade%20the%20Maven%20repository%20so,of%20the%20obsolete%20HTTP%20one.&text=Define%20a%20mirror%20in%20your%20settings.&text=Define%20an%20exception%20for%20a%20specific%20repository.&text=The%20false%3C%2F,be%20used%20as%20an%20exception.
A bit different solution that has helped me, is more related to our corporate environment and involves the fact that we are slowly moving out of maven to another dep/build tool, but there is still a 'corporate' settings.xml file defined.
So just rename it to a different file (instead of deleting), like mv settings.xml settings-backup.xml, and returning maven again would help you to check if it's the issue.
I encountered this issue when I installed a new version of maven. Fixed this by renaming .m2 directory to whatever or like .m2-old then run maven again. it will recreate the directory, the drawback is it will redownload all jar since the new .m2 is empty. Then just transfer your settings.xml to that new .m2 directory.
I've yet to test if copy the repository directory from the old .m2 to the new one will just work fine.
Update : copying the repository directory from ~/.m2-old to the new ~/.m2 didnt cause any errors when running maven afterwards
For your local environment, the quickest way is to set the blocked value from true to false in your .m2\settings.xml
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror>
I was able to compile by commenting the code:
/Applications/IntelliJ\ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml
<!--<mirror>
<id>maven-default-http-blocker</id>
<mirrorOf>external:http:*</mirrorOf>
<name>Pseudo repository to mirror external repositories initially using HTTP.</name>
<url>http://0.0.0.0/</url>
<blocked>false</blocked>
</mirror>-->
Pude compilar comentando el codigo dentro de la ruta
/Applications/IntelliJ\ IDEA.app/Contents/plugins/maven/lib/maven3/conf/settings.xml
Unblock a password protected HTTP repository
I didn't like to modify the global settings.xml of IntelliJ (probably requires fix again after every update), and the method unblocking all http-repos didn't work for me - I guess because our HTTP-repo is password protected.
What worked for me finally was a mirror entry that exactly fits the original repo:
Same ID as the repo.
Same URL as the repo (it's just a fake mirror)
mirrorOf also has that same ID.
blocked set to false of course.
Thus the mirror mirrors exactly the HTTP repo and nothing else - you need a mirror for each HTTP repo. But since the mirror has the same ID as the Repo, the authentication settings in the "server" section that refers to that repo also fits to the mirror and allows access.
<mirror>
<id>repoId</id><!-- Must fit to serverID!!! (can be same as repoID) -->
<name>My Mirror</name>
<!-- URL of the mirror - in our case just the same as the repo itself. -->
<url>http://mvn-host/content/repositories/myrepo/</url>
<mirrorOf>repoId</mirrorOf><!-- Mirrors exactly the repo itself -->
<blocked>false</blocked><!-- Unblock http access - only works in mirrors, and that's why we need a mirror. -->
</mirror>
The key to all this is that the mirror needs a server entry if it is protected.
You can use a Maven wrapper to help you with the problem, the version below 3.8.1 work well with it.
To create a Maven wrapper do
mvn -N io.takari:maven:0.7.7:wrapper -Dmaven=3.6.1
After this settings --> build, Execution, Deployment --> build tools --> Maven
Select the Maven Home Path to *Use Maven Wrapper*
Go back to your project and from the Maven Settings
This solved my issue, hope it will help you too.

Specifying the maven repository URL for getting the dependencies resolved?

I am trying to understand how maven downloads the binaries from the repositories.
For example, I have the following dependency for my project:
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.1</version>
</dependency>
Now, these binaries are present in http://mvnrepository.com/.
In pom.xml, we have <repositories> tag where we specify the repository URL from where maven can download the files, template:
<repositories>
<repository>
<id>mvnrepository_id</id>
<name>mvnrepository.com</name>
<url></url>
</repository>
Now, my doubt is, what should be the value of the <url>; does it need to be the base url , like http://mvnrepository.com/ or the complete URL --> http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs
To me it appears that is should be the base url else for each dependency we have to put the complete URL.
Can anyone help me understand this?
Unless you want to fetch artifacts from a repository different from the default Central Maven repository, you need not add the <repositories> section to your pom.xml. Read about Maven Repositories here and here.
And the url for default Central Maven repository is http://repo.maven.apache.org/maven2/.
PS: The URLs you have posted are the ones for the Website.

Adding environment dependent parameters to the build

In my company's parent POM I specify corporate repositories, that we all use. The URLs contain server name and the path of course. Each time I change the POM I publish a new version.
Now imagine, that the server hosting our repos gets renamed. I can change all URLs in the parent POM (not a problem) and publish a new version with fixed URLs. But I can't change URLs in the existing versions of the parent POM.
This means, that I can't rebuild any artifact from the past.
Is there some standard way to get around this problem? Like:
Central property file
A configuration POM with a fixed 1.0.0-SNAPSHOT version, that get republished on any change?
You never put repositories except for distMngt in your POM. Again -- never. You have burned your POMs forever. This exists in Maven because repo managers did not exist back then. It is bad practice for years now and shall be removed.
Always use a Nexus instance with a repo group. This shall be added to your settings.xml which will mirror everything.
For those who don't believe, I am a long year Maven committer.
Another approach that we employ at work is to replace the URLs in the <distributionManagement> with parameters, like so:
<distributionManagement>
<repository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.releases}</url>
</repository>
<snapshotRepository>
<id>my-repo</id>
<name>My Release Repo</name>
<url>${url.deploy.snapshots}</url>
</snapshotRepository>
</distributionManagement>
This way, we use settings.xml to control where the artifacts should be deployed. This has the advantage that if you ever migrate a repository (which we did) you only need to update settings.xml for new builds/releases.
If you need to go back to an earlier release and republish (for whatever reason) you just checkout the release tag, set up settings.xml to point to the new repo and do a mvn clean deploy.
If you can't modify settings.xml you can always just copy it, change the copy and point out the new settings file with the -s flag.
This approach also works for <scm> tags.
If you use repositories in your parent pom and may change over time, the best strategy is in the URL or it use ALIAS (DNS, Apache redirect, Rewriting) and especially not the IP address directly , and you do not have to change the address of the repository every time.
Example:
<repositories>
<repository>
<id>myrepo</id>
<url>http://myrepo.me/content/repositories/public/</url>
</repository>
</repositories>
and:
http://myrepo.me/content/repositories/public/ => ip address 1.2.3.4/*/*/

Resources