5

I'd like to have a module in some kind of global project directory, so that I can include that module in all other projects that use that common code.

But how can I then tell a maven parent pom to include and compile this global shared module? The following does not work:

svn/MyGlobalProject/project-commons/pom.xml           //should be shared among different projects
svn/MyProject/web-parent/trunk/pom.xml                //the parent pom used to build the application
svn/MyProject/web-parent/trunk/project-domain/pom.xml //submodule 1
svn/MyProject/web-parent/trunk/project-web/pom.xml    //submodule 2

parent pom.xml:

<project>
        <groupId>de.project</groupId>
    <artifactId>project-parent</artifactId>
    <packaging>pom</packaging>

    <modules>
        <module>project-domain</module>
        <module>project-web</module>
        <module>../project-commons</module> <!-- Error -->
    </modules>
</project>

mvn package results in:

Child module trunk\project-commons of trunk\pom.xml does not exist
Steve
  • 381
  • 1
  • 6
  • 16
membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

4

If you run mvn install on that global project, it will be installed in your local repository. Your other projects can then reference it as a dependency:

<dependency>
  <groupId>whatever</groupId>
  <artifactId>project-commons</artifactId>
  <version>1.0</version>
</dependency>

The downside of this simplistic approach is that your other projects won't compile until you've checked-out project-commons and run mvn install.

A more advanced approach is to deploy a network-accessible repository (such as Artifactory or Nexus) which you can deploy global artifacts to. Artifactory has a community edition which is free. You can then list this repository in your settings file and Maven will resolve artifacts that are uploaded to it.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
  • I'm trying to use the submodule approach to exactly avoid having to mvn install the project into repo. – membersound May 28 '14 at 13:07
  • @membersound Why? That is *exactly the purpose* of `mvn install`. To try and avoid this is to fight the very essence of Maven. I would recommend the Artifactory approach myself - easy to install and lots of benefits. – Duncan Jones May 28 '14 at 13:08
  • Hm ok. Is there any way to automatically detect changes in the commons when I deploy my module project that has a dependency to commons? – membersound May 28 '14 at 13:11
  • @membersound You can use the special version number `LATEST` or `RELEASE` to always refer to the newest commons artifact (snapshot and non-snapshot respectively). But this is frowned upon in the Maven community because it can lead to build instability. See [this question](http://stackoverflow.com/questions/30571/how-do-i-tell-maven-to-use-the-latest-version-of-a-dependency) for more info. – Duncan Jones May 28 '14 at 13:12
  • What if we need `project-commons` as a module itself, which can be used under profiles? Basically, I have several profiles in my pom and need `project-commons` as part of couple of the profiles. @DuncanJones – Steve Jul 09 '18 at 12:21
0

Using relative path to include some submodules is not a good practice...you will have a lot of problems.

Can not you just put the common project as a dependency of the parent module...

In this way you will have that "common project" in all the submodule that declare the parent project as a parent...

Why do you want to compile your "common" project every time you compile the parent pom?

Edited:

YOUR SVN:

svn/MyGlobalProject/project-commons/pom.xml           //should be shared among different projects
svn/MyProject/web-parent/trunk/pom.xml                //the parent pom used to build the    application
svn/MyProject/web-parent/trunk/project-domain/pom.xml //submodule 1
svn/MyProject/web-parent/trunk/project-web/pom.xml    //submodule 2

PARENT POM.XML:

<project>
    <groupId>de.project</groupId>
    <artifactId>project-parent</artifactId>
    <packaging>pom</packaging>

    <dependencies>
       <dependency>
      <groupId>de.project</groupId>
      <artifactId>project-commons</artifactId>
      <version>${common.project.version}</version>
       <dependency>
    <dependencies>

<modules>
    <module>project-domain</module>
    <module>project-web</module>
</modules>

Just like this... in that way project-domain and project-web will inherit that dependency, and you will able to use it everywhere you want in submodules...

Than the use of dependency management could be a good improvements

Michael Easter
  • 23,733
  • 7
  • 76
  • 107
ivoruJavaBoy
  • 1,307
  • 2
  • 19
  • 39
  • Could you give an example of this architecture? It sounds like maybe it's the right approach. I do not necessairly want to compile my common project every time. But I at least want it to be resolved from workspace by maven, and not having to install it in the maven repo. – membersound May 28 '14 at 13:08
  • You can't declare a dependency until the artifact has been installed somewhere. Hence my answer. This answer just suggests an alternative way to incorporate that dependency into a lot of children, which might be a sensible approach. – Duncan Jones May 28 '14 at 13:11
  • @ivoruJavaBoy ok but this would me also require to having installed the commons dependency into local repo. Then I could as well directly add the dependency to each module that requires it. – membersound May 28 '14 at 13:27
  • Yes...but I can not seem to find it difficult to install common project individually...As @membersound asks.. you can use some free Continous integration tools (like apache Continuum) to re-build and re-deploy on you remote repository (artifcatory, nexus) the common project after every commits...in that way you will be sure to use always the last SNAPSHOT of common project – ivoruJavaBoy May 28 '14 at 13:28