How to specify maven's distributionManagement organisation wide?

mglauche picture mglauche · Jul 21, 2010 · Viewed 112.6k times · Source

I'm trying to figure out how to organize many (around 50+) maven2 projects, so that they can deploy into a central nexus repository. When using the mvn deploy goal, one does need to specify the target in the distributionManagement tag like this:

<distributionManagement>
   <repository>
      <id>nexus-site</id>
        <url>http://central_nexus/server</url>
   </repository>
</distributionManagement>

Now, i don't want every single pom.xml (of those 50+) to contain this block over and over again. My first though would be the settings.xml file, but it seems it is not possible (by design) to define it there. So, the first question would be, why is that the case ? If it would be possible i could specify it in the settings.xml in the maven2 distribution, which could be distributed to all developers.

The only possible solution i've found was to create an organisation-wide master-pom project, that does contain these settings, and make all other pom.xml depend on this master-pom via <parent> tag. But this looks kind of strange in multi-module builds:

- master configuration POM (pm)
- Project 1 parent pom (p1 with module 1 and module 2 as modules)
    - Project 1 module pom (with pm as parent)
    - Project 2 module pom (with pm as parent)

Usually i read in all documentation that the module poms should use the parent pom, not some different one. But after reading the maven website about Inheritance v. Aggregation it is written that it is indeed possible.

One problem i found was with the maven site generation, which does seem to have problems with this setup (modules does not get linked correctly if they have no direct back-reference)

So, is this a valid approach ? Any other, more obvious, simpler solution to the problem ?

Answer

Jesse Webb picture Jesse Webb · Jul 21, 2010

The best solution for this is to create a simple parent pom file project (with packaging 'pom') generically for all projects from your organization.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>your.company</groupId>
    <artifactId>company-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <distributionManagement>
        <repository>
            <id>nexus-site</id>
            <url>http://central_nexus/server</url>
        </repository>
    </distributionManagement>

</project>

This can be built, released, and deployed to your local nexus so everyone has access to its artifact.

Now for all projects which you wish to use it, simply include this section:

<parent>
  <groupId>your.company</groupId>
  <artifactId>company-parent</artifactId>
  <version>1.0.0</version>
</parent>

This solution will allow you to easily add other common things to all your company's projects. For instance if you wanted to standardize your JUnit usage to a specific version, this would be the perfect place for that.

If you have projects that use multi-module structures that have their own parent, Maven also supports chaining inheritance so it is perfectly acceptable to make your project's parent pom file refer to your company's parent pom and have the project's child modules not even aware of your company's parent.

I see from your example project structure that you are attempting to put your parent project at the same level as your aggregator pom. If your project needs its own parent, the best approach I have found is to include the parent at the same level as the rest of the modules and have your aggregator pom.xml file at the root of where all your modules' directories exist.

- pom.xml (aggregator)
    - project-parent
    - project-module1
    - project-module2

What you do with this structure is include your parent module in the aggregator and build everything with a mvn install from the root directory.

We use this exact solution at my organization and it has stood the test of time and worked quite well for us.