78

My company's policy frowns upon artifacts downloaded automatically (they have to be approved), so in order to use Maven I need to disable access to Maven's central repository.

In other words, I don't want Maven to attempt any downloads from central.

I know how to configure a local repository (networked or not), my idea is using a "blessed" machine to update the local repository.

PS: I could block requests at the proxy/network level, but I'm asking about how to do it with Maven's configuration.

UPDATE I finally figured out how to do it. In maven's home, in the conf directory is a global settings.xml. You can either set a mirror to central that points to some internal server or just override it's definition.

juancn
  • 2,483
  • 2
  • 20
  • 25

7 Answers7

69

Agreed. No direct downloads from external repositories should be allowed in your release builds.

The specific answer to your question is the second part of my answer :-)

Setup a repository manager

I'd recommend setting up a local Maven repository manager. Good options are the following:

All of these are capable of acting as a caching proxy for the externally available Maven central jars.

You might also be interested in the Profession version of Nexus. It includes a Procurement suite for managing external libraries. It also provides Maven plugins for centrally managing the Maven settings file, which is the second part of my answer...

Local Maven settings

Update the settings file located in the following directory:

$HOME/.m2/settings.xml

Specify that all central requests should be redirected to the local Maven repository:

<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-proxy</id>
      <name>Local proxy of central repo</name>
      <url>http://<hostname>/central</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
  </mirrors>
  ...
</settings>
dzikoysk
  • 1,560
  • 1
  • 15
  • 27
Mark O'Connor
  • 76,015
  • 10
  • 139
  • 185
  • 4
    Artifactory (even in OSS edition) can generate this settings file for you - http://wiki.jfrog.org/confluence/display/RTF/Configuring+Artifacts+Resolution – JBaruch Apr 06 '13 at 18:29
  • 1
    The "central" here should be lowercase: central. The central cannot be replace when I use "Central" here. – paco alcacer Sep 13 '17 at 09:18
63

I found the Configuring Artifacts Resolution page helpful. It states the following about the "mirror any"-setup.

Don't use "mirror any" by itself, as your only resolution rule. Use it to enforce any artifacts resolution to be made strictly through Artifactory. The "mirror any" proxying configuration works for defined repositories. It will supersede, but not hide, the built-in central and snapshots repositories, unless overridden by the user. It defines a coarse-grained proxying rule that does not differentiate between releases and snapshots, and relies on the defined repositories to do this resolution filtering.

The Super POM of Maven defines the central respository. Here is how you can override the central repository and the plugin-repository for releases and snapshots:

<repositories>
    <repository>
        <id>central</id>
        <url>http://repo1.maven.org/maven2</url>
        <releases>
                <enabled>false</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>    
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <url>http://repo1.maven.org/maven2</url>
        <releases>
            <enabled>false</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
</pluginRepositories>

Of course you should have a replacement configured, as the accepted answer stated.

Behe
  • 7,572
  • 3
  • 33
  • 46
  • 3
    This solution seems the best we can currently get. There are still problems if you use different projects with the same local repository (if the other project don't care about deactivating maven central), but as long as we can't completely remove the central repository this is clean and does not depend on a mirroring repository manager. – dag Feb 29 '16 at 09:37
  • 3
    URL is now https://repo.maven.apache.org/maven2/ – caduceus Sep 02 '22 at 10:28
8

In case of a company-wide repository which should handle all and every artifact request you can configure a single repository to mirror everything in your $MAVEN_HOME/conf/settings.xml:

<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>

Source

SnakE
  • 2,355
  • 23
  • 31
  • 1
    Apparently overriding central doesn't catch if some plugins or artifacts have added their own repo's so this way is better, FWIW. https://stackoverflow.com/a/22081916/32453 – rogerdpack Mar 08 '21 at 19:14
6

In the past I have found that the most robust solution is to manually override the built-in repositories. I found this approach better than changing the parent POM, settings.xml, mirror, or profiles. For all internal projects put below settings into their POM.

<repositories>
    <repository>
        <id>central</id>
        <url>http://internalrepo</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
    <repository>
        <id>snapshots</id>
        <url>http://internalrepo</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <url>http://internalrepo</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </pluginRepository>
    <pluginRepository>
        <id>snapshots</id>
        <url>http://internalrepo</url>
        <releases>
            <enabled>false</enabled>
        </releases>
    </pluginRepository>
</pluginRepositories>
Jose Martinez
  • 11,452
  • 7
  • 53
  • 68
5

The simplest way is to use the -o parameter which tells maven to run in offline mode. Of course you will need to ensure your local repo has everything you need, but this at least sorts out any security worries you may have with connecting automatically to an unapproved repo.

Rory Alsop
  • 1,441
  • 25
  • 38
  • By "local repo" you mean the local machine right? All of the dependencies will need to be installed locally because -o causes maven to never use an off-box repo. – Gray Jul 10 '19 at 14:57
  • Of course, @Gray - that is what the offline mode does :-) – Rory Alsop Jul 10 '19 at 15:22
  • I know Rory. It was just your use of the term "local repo" which could be mistaken to be the repo that was local to your company. Just trying to be explicit for the n00bs out there. – Gray Jul 10 '19 at 20:45
  • No worries @Gray – Rory Alsop Jul 10 '19 at 22:54
4

Sounds like someone is actively trying to enforce your Open Source governance policy. That's good to hear.

Agree with the other comment here about using an internal repository manager to host the components needed by Maven.

As Rory mentions, you need to make sure you have everything needed in that repository before you stop access to Maven Central (The Central Repository) or any other public open source repository.

Mark makes a good point about the Nexus procurement capabilities. Once that internal repo manager is set up with all of your "approved" components, you can also turn on the Nexus Repository Health Check feature (it's free), that reports on all of the component licenses, known security vulnerabilities, etc. for components in your repos.

Full disclosure, I work for Sonatype.

-1

I had the same problem but with an other cause. The solution was to deactivate Avira Browser Protection (in german Browser-Schutz). I took the solusion from m2e cannot transfer metadata from nexus, but maven command line can.

Community
  • 1
  • 1
iuzuz
  • 69
  • 6