Thursday, March 27, 2014

Maven respository configuration in settings.xml

The following is an analysis on the maven configuration file settings.xml. In this example, it is assumed that you are working on a computer that is in your company office. So it uses a company proxy to go to the internet. Assume the company name is MyCompany. The maven version in this analysis is 2.2.1.
  1. Maven has its own settings.xml. This is a global file in C:\apache-maven-2.2.1\conf. But the file content is basically all commented out. So it is basically just a placeholder there.
  2. Maven then uses the settings.xml in the user directory C:\Users\userid\.m2
  3. Inside MyCompany network, the http traffic usually uses a proxy.
  4. For IE browser, you can configure the proxy by following the menu: tools --> internet options --> connections - LAN settings. Then you can check "Use Automatic configuration script" and set the URL to the script in the "Address" input field. For example, you can specify the following in the Address: http://autoproxy.MyCompany.com/.
    If the MyCompany proxy is not set, it seems that no traffic can go outside. Even the URL www.google.com will time out. And the central maven repository http://central.maven.org/maven2/ will time out too of course.
  5. For maven, the proxy is configured using the<proxy> tag inside the settings.xml file. For example:
     <proxies>
        <proxy>
           <active/>
           <port>80</port>
           <host>internet.myCompany.com</host>
           <id>my proxy</id>
           <nonProxyHosts>*.myCompany.com</nonProxyHosts>
        </proxy>
     </proxies>
     
  6. Maven uses the Central Repository http://central.maven.org/maven2/ as the default repository. Even if you do not specify any repository in the settings.xml file, maven will use this Central repository.
Because of the license issues, it can be expected that MyCompany needs to have a repository that hold all the permitted java libraries. It will be wrong for the application to be able to download libraries from outside repositories freely, even if it is the central maven repository. So how to achieve this? The trick is in the "mirror" configuration in the settings.xml. There are documents here: https://maven.apache.org/guides/mini/guide-mirror-settings.html. The following are the important things.
  1. By default, Maven will download from the central repository. To override this, you need to specify a mirror.
  2. 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 *.
  3. The official Maven 2 repository is at http://repo.maven.apache.org/maven2 hosted in the US.
  4. The ID of the main Maven Central US repository included by default is central.
At MyCompany, the production settings.xml has the following:
   <mirrors>
     <mirror>
          <id>maven.MyCompany.com</id>
          <name>Maven Repository Manager running on maven.MyCompany.com</name>
          <url>http://maven.MyCompany.com/m2</url>
          <mirrorOf>central</mirrorOf>
     </mirror>
   </mirrors>
    
    <repositories>
           <repository>
             <id>mvnown</id>
             <name>Maven Repository Manager running on maven.MyCompany.com</name>
             <url>http://maven.MyCompany.com/m2</url>
           </repository>
     </repositories>
  
From the above, we can see that the maven "central" repository is overridden by the MyCompany repository. The only repository used is http://maven.MyCompany.com/m2. In one project, we got the following error messages when building the application:
Downloading: http://maven.MyCompany.com/m2/org/jboss/jboss-parent/6/jboss-parent-6.pom
[INFO] Unable to find resource 'org.jboss:jboss-parent:pom:6' in repository mvnown (http://maven.MyCompany.com/m2)
Downloading: http://maven.MyCompany.com/m2/org/jboss/jboss-parent/6/jboss-parent-6.pom
[INFO] Unable to find resource 'org.jboss:jboss-parent:pom:6' in repository central (http://repo1.maven.org/maven2)
You can see that maven tried the two repositories: Firstly repository mvnown (http://maven.MyCompany.com/m2). Secondly central (http://repo1.maven.org/maven2).

The first repository is specified in the<repository> setting. The second repository is the default. This error message shows that even if you do not specify the central repository in the settings.xml, maven will still try to download libraries from that repository. In our case, it is mirrored. So what maven got is actually still mvnown (http://maven.MyCompany.com/m2)! And of course, nothing new is found there!

Now if I remove the mirror for the central, what will happen? Can maven find that jboss-parente-6.pom file? You will expect that the answer should be a "Yes". And that is right! It will be found and the build will be a success!