68

We have Java and Flex projects. We currently have 1 base pom that contains the configurations we want to use for both projects. Problem with this is: Flex projects inherit configuration, for example, for javadoc and pmd plugins, which is not desirable.

I want to clean it up and have a real base pom, and then a java-base-pom and a flex-base-pom. But how does this work in a multi-module that has both a Flex part and a Java part?

We have plugins to our own application where we use the following structure:

  • my-plugin
    • my-plugin-client (flex)
    • my-plugin-server (java)

my-plugin just contains a pom.xml with <modules/> section. I would use my-plugin pom.xml as a parent for both, but then I cannot also use the java base-pom or the flex base-pom as parent. What would be the best approach for this?

Ondra Žižka
  • 36,997
  • 35
  • 184
  • 250
Wim Deblauwe
  • 19,439
  • 13
  • 111
  • 173
  • I think I am asking know a similar question at https://stackoverflow.com/questions/57449258/maven-unreachable-parent-pom-in-unusual-relations-setup – Ondra Žižka Aug 13 '19 at 14:23

6 Answers6

39

Even though maven projects have single parent, they can import any number of other pom's like this:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>my-shared-dependencies</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

This has two important differences compared to a parent:

  1. Plugins defined in the imported pom won't be imported
  2. Dependencies defined in the imported pom won't be added to the current pom, it will only import dependencies into the dependency management section

However, if your parent pom has a <dependencies> section and you want to include those into your dependencies, then you can add the parent to your <dependencies> section just like a regular dependency:

<dependency>
    <groupId>org.example</groupId>
    <artifactId>my-shared-dependencies</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Even though the same dependency is already imported, the version tag has to be specified again. To reduce duplication, it can be stored in a property

Brad Turek
  • 1,629
  • 1
  • 24
  • 46
Peter Szanto
  • 6,723
  • 2
  • 43
  • 50
38

A project can have only one parent (unlike multiple inheritance in C++) but this parent can be part of a bigger parent hierarchy. As pointed out by others, you could thus have something like this:

base-pom/
|-- flex-base-pom
|   |-- my-plugin-client
|   |   `-- pom.xml
|   `-- pom.xml
|-- java-base-pom
|   |-- my-plugin-server
|   |   `-- pom.xml
|   `-- pom.xml
 `-- pom.xml

That said, I noticed you wrote that your actual problem is that:

flex projects inherit configuration for javadoc and pmd for example, which they do not want.

You should use the pluginManagement element to avoid this situation:

pluginManagement is an element that is seen along side plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one. However, this only configures plugins that are actually referenced within the plugins element in the children. The children have every right to override pluginManagement definitions.

So, in the parent pom, configure your plugins in pluginManagement (javadoc and pmd for example), and reference them within the plugins element in the desired children (only in my-plugin-server here). This would solve your current issue.

Pascal Thivent
  • 535,937
  • 127
  • 1,027
  • 1,106
  • Thanks for the answer, but like I said in a comment to the other answer, this is not a structure I can use. If nothing else pops up, then pluginManagement might be the only way to do it. Drawback is then that I cannot enforce PMD on all java projects, since it is only in the pluginManagement and the project itself has to add it to his own plugin section. – Wim Deblauwe Oct 28 '09 at 19:22
  • Accepting this as the answer. With the current state of Maven, using pluginManagement will be the best solution. – Wim Deblauwe Jan 13 '10 at 12:44
6

The only way is to have base-pom as parent of java-base-pom and flex-base-pom.

I have similar structure for my spring projects:

base-pom (basic configuration - eclipse, reports, repositories, etc)
|
+ spring-base-pom (spring definitions)
  |
  + spring-jar-base-pom (jar specific definitions)
  |
  + spring-war-base-pom (spring web and servlet dependencies)
    |
    + spring-webapp-base_pom (spring web mvc dependencies)
David Rabinowitz
  • 28,033
  • 14
  • 88
  • 124
  • Agreed. How would multiple parents work anyway - what would happen if both parents had conflicting properties? – matt b Oct 28 '09 at 13:01
  • The child overrides the parent, so settings in java-base-pom will override those of base-pom, child1 those of java-base-pom, etc. This way java-base-pom and flex-base-pom are unrelated. – David Rabinowitz Oct 28 '09 at 13:08
  • I am having difficulties doing multiple levels of hierarchy - on my third level (analogous to your spring-webapp-base_pom) the pluginManagement part from parent gets omitted altogether. Any ideas why this happens? – Neikius Dec 24 '15 at 11:34
4

I've cross this exact proble also, and the best solution I found was to use Inheritance and Aggregation as suggest in this question : does maven support multiple parents (multiple inheritance) ?

You can have an aggregator pom that is not the parent of the projects it aggregates.

and explain in the Maven Documentation

Inheritance and aggregation create a nice dynamic to control builds through a single, high-level POM (...) Conversely, a POM project may aggregate projects that do not inherit from it.

From this I had my POMs inheritance (pom-master contains communes configurations, and each children the specifics ones) :

pom-master
  |-- pom-java
  |-- pom-flex

and so my project can get the specifics for each modules configurations as wished :

project (aggregate project-flex & project-java)
  |-- project-java
  |      `-- pom.xml => parent = pom-java
  |-- project-flex
  |       `-- pom.xml ==> parent = pom-flex
  `-- pom.xml => parent = pom-master

Hope it will help others as well :)

LE GALL Benoît
  • 5,165
  • 1
  • 31
  • 45
2

Just image that pom.xml are in fact Java classes: you can have only one parent (or extends a class), but this parent can also have another parent, and so on.

As I explained here, you must distinguish the parent and aggregation principles in Maven, which means that my-plugin would be considered as an aggregation project, not necessarily a parent project for both my-plugin-client and my-plugin-parent.

So to summarize:

my-plugin will define the base pom for all your projects. Then, you create two new pom projects: java-base-pom and flex-base-pom. They have both my-plugin as parent. Now, my-plugin-client will have java-base-pom as parent, while my-plugin-server will use flex-base-pom for his parent.

This way, my-plugin-client will inherit all properties defined in the my-plugin pom.xml, and also from java-base-pom project.

Community
  • 1
  • 1
Romain Linsolas
  • 73,921
  • 45
  • 197
  • 265
  • Maybe I did not make myself clear enough. The base poms should be at the root of the hierarchy because the application itself also depends on it, or any other java module we build. It is just that next to that I also have this plugin structure which would need kind of 2 parents, but this is not possible it seems. – Wim Deblauwe Oct 28 '09 at 19:20
0

You can achieve multiple inheritance with profiles:

You create (multiple) profiles in the root pom, and auto activate any variation of these profiles achieves multiple inheritance of maven configuration.

sibidiba
  • 5,974
  • 7
  • 35
  • 50
  • This is not ideal because child projects cannot control the activation of profiles defined in the parent POM. – GuyPaddock Oct 21 '17 at 15:41
  • This is not remotely related to inheritance. But you can use them to setup some parameters to turn on/off with a switch (enabling/disabling the profiles). – Shadow Man Apr 20 '18 at 23:39