views:

1598

answers:

4

I know it's mauvais ton to ask twice in a single day but here's another Maven puzzler:

I have a parent POM which defines 5 modules (5 subprojects). Since each module is executed in exactly the same way I pull <profile><build> section into the parent POM to get rid of the duplicate code. Now - if I execute build individually from each module it works, however if I want to build all modules at once and move to the parent directory I got error since the very first thing Maven tries to execute is the parent project itself:

mvn package -P release
[INFO] Scanning for projects...
[INFO] Reactor build order:
[INFO]   DWD Parent project
[INFO]   Projects

After that build fails because exec plugin tries to execute something that is not there. Looking at the output it is pretty obvious that reactor plugin is driving the build but how can I configure reactor to skip the parent?

P.S. To prevent confusion - I'm trying to suppress profile execution on parent and enable it on child during the same build

+2  A: 

You can't skip the parent build, but you can configure the profile to not be activated with a little hack. This answer shows how to control the activation of a profile by the presence or absence of a file-based <activation> element. This way you can define the profile in the parent, but have it deactivated in that project because of the marker file being present in the parent. Child projects would not have the marker file in their source, so the profile would be activated for those projects.

Update to clarify: On my test project this configuration means the profile is deactivated in the parent project (which has the file in src/main/resources), but activated in all child projects which do not have the file in their resources directories.

<profile>
  <id>test</id>
  <activation>
    <file>
      <missing>src/main/resources/test.marker</missing>
    </file>
  </activation>
  ...
</profile>
Rich Seller
Rich - that's the answer I want! To the points of romanitaz - I want both: aggregation and ability to pull common code to the parent (to whom executing that code makes no sense).
DroidIn.net
Rich - if I can bother you a little bit more. I'm trying to achieve the same effect by using property instead of missing file. It doesn't work. Even when I stick property declaration into my child's POM my profile is never activated. Why is that? Are the properties declared "pre-built" and never reset? Maybe I should ask another question so I can put code example?
DroidIn.net
No it should activate based on property presence (there is an example at http://maven.apache.org/guides/introduction/introduction-to-profiles.html), feel free to ask another question if you can't get it working
Rich Seller
My head is spinning :( Can't make it work using property http://is.gd/3QLtl. And it doesn't work with file marker ether. I have build.terminator file in the top folder of my parent (next to pom.xml). If I refer to it in activation section as `<missing>build.terminator</missing>` - file is found and profile is not executed for both parent and child. If I change to `<missing>${basedir}/build.terminator</missing>` then both parent and child are executed which means that Maven cannot see the file? What gives?
DroidIn.net
updated with an example
Rich Seller
Negative. Put file in parent's resources, coded exact syntax as in your example, both parent and child will not execute
DroidIn.net
Sorry Rich - I would have to remove "Answered" checkmark. Your solution will work perfectly for build execute ether from parent or from child. I'm talking about "skipping" profile in parents and continue the execution in child during the same build cycle. I think that's where confusion is coming from - I'll modify the original post
DroidIn.net
+3  A: 

What is wrong by building the parent?

In fact, in Maven, there are two different concepts (which are generally used at the same time):

  • The parent POM
  • The modules aggregation

The first one is a definition of everything that is common with all the children. You define a parent as a pom-packaged project, and you can install it in your repository.

When you build a child of this parent, Maven2 will retrieve this parent to merge the parent pom with the child pom. You can have a look to the entire pom.xml by running the command mvn help:effective-pom.

In this case, the parent pom will not be built, it will just be retrieved from the repository.

The second case is a project that contains a modules list of sub-projects. The principle is that every command that you run on this project will also be run on all the sub-modules. The order of the modules will be defined by the Reactor, which will look at inter-modules dependencies to find which module must be built before the others. If there are no dependencies, then it will take the list of the modules as they are defined in the parent pom.xml.

In this case, if you run a command on the root project, Maven2 will first built the root project, and then the sub-modules. You cannot skip the creation of the root project.


Edit, thanks to RichSeller comment

A complete explanation of the differences between multi-modules (aggregation project) and inheritance (parent project) can be found in the Maven book, here.

romaintaz
+1 for pointing that out, see the Maven book for more details: http://www.sonatype.com/books/maven-book/reference/pom-relationships-sect-multi-vs-inherit.html
Rich Seller
Yes, I wanted to point that because generally people think that aggregation and parent project are the same thing and can't be used separately.
romaintaz
What's wrong with building the parent? Simple - what happens in profile is applicable to children but makes no sense for parent. To your point - I need both: aggregation and ability to pull up reusable code. Profile activation - as commented by Rich Seller is the perfect solution
DroidIn.net
Or maybe would be perfect solution. So far I can't make it work
DroidIn.net
+1  A: 

I want to document that there's partial compromise to my situation (thanks to guys on maven users mailing list for suggestion). Basically you need to chop profile in two pieces. Reusable configuration section of plugin goes to the parent POM, and executions stays in the child POM. Then the profile plugin in the child is marked as inherited and voila - at run time parent profile is not executed since it's missing executions section. This is far from ideal but it does work. Refer to this link for example

DroidIn.net
Interesting, thanks for posting this here. However, does the link work or is it just me?
Pascal Thivent
Works for me, but you can try full versionhttp://mail-archives.apache.org/mod_mbox/maven-users/200812.mbox/%[email protected]%3E
DroidIn.net
The full version works, not the shorten one. Thank you.
Pascal Thivent
Pascal - you may want to look at my latest comment
DroidIn.net
A: 

I wasn't able to implement "missing" file solution as provided by Rick Seller above. It seems that once set active/non-active state of profile will not be changed even the marker file is missing from the module(s). However here's the exact solution to my problem. Warning: this is only available starting with Maven 2.1+

If I have a parent POM with 2 modules defined: foo and boo then in regular circumstances order of execution will be:

  1. parent
  2. foo
  3. boo

All I need to do to skip parent build is to add this command line switch

mvn install –rf foo

Alternatively you can use --resume-from What it will do is to skip parent and continue from foo module down. Now - I'm investigating if this can be achieved by configuring Reactor plugin (P.S. - no it can't) but even with the switch, the above scenario works fine for me

DroidIn.net