Search code examples
javamaven-2mavenrelease-management

How to define organization specific parent pom


Env: Maven 2.2.1 I have two java projects under svn (projectA, projectB). My maven structure is as follows..

For projectA 
pom.xml (contains ProjectA parent pom definitions)

   module moduleA
   module moduleB


For projectB 
pom.xml (contains ProjectB parent pom definitions)

   module moduleC
   module moduleD

projectA/pom.xml and projectB/pom.xml contain common definitions like junit, selenium, compiler, eclipse plug-ins which are common to both projects. (e.g. given below)

    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.7</version>
        <scope>test</scope>
    </dependency

How should I create / organize a organization specific project pom which includes such common definitions, so that individual projects don't have to re-create / maintain one. Can someone provide some snippets or projects which have already done this before?

EDIT1:

company/pom.xml

<modelVersion>4.0.0</modelVersion>

<groupId>com.mycompany</groupId>
<artifactId>company</artifactId>
<packaging>pom</packaging>

<name>parent</name>
<version>1.0.0</version>

<build>
    <defaultGoal>install</defaultGoal>
</build>

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
        <type>jar</type>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

projectA/pom.xml

<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>com.mycompany</groupId>
    <artifactId>company</artifactId>
    <version>1.0.0</version>
</parent>

<groupId>com.mycompany</groupId>
<artifactId>projectA</artifactId>
<packaging>pom</packaging>

<name>projectA</name>
<version>1.0.0</version>

<modules>
    <module>moduleA</module>

<build>
    <defaultGoal>install</defaultGoal>
</build>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

projectA/moduleA/pom.xml

<modelVersion>4.0.0</modelVersion>

<parent>
    <groupId>com.mycompany</groupId>
    <artifactId>projectA</artifactId>
    <version>1.0.0</version>
    <relativePath>../pom.xml</relativePath>
</parent>

<groupId>com.mycompany</groupId>
<artifactId>moduleA</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

<name>moduleA</name>

<build>
    <finalName>moduleA</finalName>
    <defaultGoal>install</defaultGoal>
</build>

<dependencies>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
    </dependency>
</dependencies>

Throws the following error:

Project ID: com.mycompany:moduleA
POM Location: c:\temp\maven\projectA\moduleA\pom.xml
Validation Messages:

    [0]  'dependencies.dependency.version' is missing for commons-lang:comm
ons-lang:jar
    [1]  'dependencies.dependency.version' is missing for javax.servlet:ser
vlet-api:jar

Solution

  • If it's only dependencies that you need to reuse, create another project with packaging pom and specify dependencies there. Let's call it OrgDependencies Then include it as dependency in your projectA and projectB. It will transitively pull all dependencies from OrgDependencies project.


    In your example, in projectA, instead of

    <parent>
        <groupId>com.mycompany</groupId>
        <artifactId>company</artifactId>
        <version>1.0.0</version>
    </parent>
    

    Try putting

    <dependencies>
      <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>company</artifactId>
        <version>1.0.0</version>
      </dependency>
    </dependencies>
    

    And remove dependencies to commons-lang etc from modules.


    Update.

    While my previous solution with transitive dependencies should work, actually what you need is <dependencyManagement> section in your company wide pom.xml

    That's where you define versions.

    Note: Anything in dependencyManagement section is not really a dependency but just a descriptor that allows to specify version and exclude transitive dependencies (if necessary) in case normal dependencies section specifies that dependency. So you can put as many items in dependencyManagement as you want, it will not make all descendants dependent on them.

    I tested it and it works:

    <?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/xsd/maven-4.0.0.xsd">
    
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.mycompany</groupId>
        <artifactId>company</artifactId>
        <packaging>pom</packaging>
    
        <name>parent</name>
        <version>1.0.0</version>
    
        <build>
            <defaultGoal>install</defaultGoal>
        </build>
    
        <dependencyManagement>
            <dependencies>
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.4</version>
                <type>jar</type>
                <scope>compile</scope>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
                <scope>provided</scope>
            </dependency>
            </dependencies>
        </dependencyManagement>
    </project>