You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by Trevor Harmon <tr...@vocaro.com> on 2008/11/13 16:57:28 UTC

Sharing modules among multi-module projects

There's an example in Chapter 6 of "Maven: The Definitive Guide" that  
shows how to set up and use a multi-module project. It's structured  
like this:

\- Simple Parent Project
    +- Simple Weather API
    +- Simple Web Application Project

With this setup, you can do "mvn install" on the parent project, and  
any out-of-date source code in any child project will automatically be  
compiled. So instead of running "mvn install" on each child, you can  
do it just once on the parent. Nice!

However... What if you now want to create a new web application  
project? Let's say this new web application is completely independent  
of the old one, but it still uses Simple Weather API.

I guess one approach is to create a new multi-module project like this:

\- Simple Parent Project 2
    +- Simple Web Application Project 2

Then simply add a dependency on Simple Weather API. But the problem  
here is that if you change the source code in Simple Weather API,  
running "mvn install" on Simple Parent Project 2 won't compile the  
change! You have to switch to Simple Weather API, run "mvn install",  
and then return to Simple Parent Project 2. This is really annoying,  
especially if you have more than one shared module.

Is there any way to set up multi-module projects so that they can  
share a module, and both projects can detect when that module's source  
code is out-of-date? Thanks,

Trevor


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sharing modules among multi-module projects

Posted by Trevor Harmon <tr...@vocaro.com>.
On Nov 13, 2008, at 5:26 PM, Wayne Fay wrote:

> Bear in mind that it is not sufficient to look at the file timestamps
> in target vs source and say "target files are all newer than source,
> therefore no changes" due to the possibilities of changes coming in
> via dependencies (including transitive ones), changes in plugins (if
> they aren't locked down, or if they are snapshots), etc.

A change in a dependency or plugin would mean a change in a pom.xml,  
right? So Maven could simply compare the dates of the artifact with  
the dates of the associated POMs.

> Part of your
> build may be to grab another jar (versioned as snapshot), unpack it,
> and use it during this project's build

I hadn't thought of this possibility. Is it a normal Maven use case? I  
don't see why it would be necessary.

Trevor


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sharing modules among multi-module projects

Posted by Wayne Fay <wa...@gmail.com>.
> But then, this seems like a Maven bug. Why go through the install process
> for a project if its source code hasn't changed?

As soon as you can figure out how Maven can consistently, reliably,
and definitively tell that an artifact has not changed before building
it, we can talk about how it might be implemented in Maven.

Bear in mind that it is not sufficient to look at the file timestamps
in target vs source and say "target files are all newer than source,
therefore no changes" due to the possibilities of changes coming in
via dependencies (including transitive ones), changes in plugins (if
they aren't locked down, or if they are snapshots), etc. Part of your
build may be to grab another jar (versioned as snapshot), unpack it,
and use it during this project's build -- without doing that, how do
you know what the results will be in advance?

As such, the only way to know if the output of a given project is
different from the last build is to do the build itself, right?

If you are really unhappy about this situation, you can use profiles
or simply multiple parent poms that specify collections of modules
rather than invoking all of them. But I think you will run into
troubles with versions before too long.

Wayne

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sharing modules among multi-module projects

Posted by Trevor Harmon <tr...@vocaro.com>.
On Nov 13, 2008, at 1:23 PM, Wayne Fay wrote:

> I would tend towards the first one if you require both projects to
> "detect when a shared module is out-of-date" as you have stated.

That's actually the approach our team is using now. The problem is  
that we've got quite a large number of projects. Something like this:

\- Simple Parent Project
   +- Simple Weather API
   +- Simple Web Application Project
   +- Simple Web Application Project 2
   +- Simple Web Application Project 3
   +- ...
   +- ...
   +- Simple Web Application Project 17

And so when we do "mvn install" on the parent project, Maven goes  
through every module and does an install on it, copying the JAR to the  
local repository. This takes a lot of time, even if there's only one  
source code change.

Perhaps something like this would work better:

\- Simple Parent Project (does not include module definitions, only  
repository and SCM info)
   \- Libraries (specifies each child as a module)
     +- Simple Weather API
     +- Some Other API
     +- Yet Another API
   \- Applications (no module definitions)
     +- Simple Web Application Project
     +- Simple Web Application Project 2
     +- Simple Web Application Project 3

With this approach, each application project would declare "Libraries"  
as a module. I could then do "mvn install" on an application project,  
and it would build only the Libraries module (with all of its  
children) and the one application, filtering out the rest.

The only problem is that as the number of libraries grows, so too does  
the build time, even if the application only depends on one or two  
libraries. So I'm back to the same issue of the build taking too long  
as Maven goes through each module and does an "install" on it.

But then, this seems like a Maven bug. Why go through the install  
process for a project if its source code hasn't changed?

Trevor


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sharing modules among multi-module projects

Posted by Nick Stolwijk <ni...@gmail.com>.
My first suggestion is to completely separate the development and
release cycle of your common modules.

Otherwise:

> \- Shared parent project
>   -- Simple Weather API
> +- Simple Parent Project
>   -- Simple Web Application Project
> +- Simple Parent Project
>   -- Simple Web Application Project 2

And in the pom of your shared parent project create a <modules> tag
with the "Simple Weather API" module and two profiles, each one adding
one of the other modules.

<profiles>
  <profile>
     <id>WAP</id>
     <modules>
        <module>Simple Parent Project</module>
     </modules>
  </profile>
  <profile>
     <id>WAP-2</id>
     <modules>
        <module>Simple Parent Project 2</module>
     </modules>
  </profile>
</profiles>

mvn install will now only compile the common module.

mvn install -PWAP will install the common module and the first web app.
mvn install -PWAP,WAP-2 will install the common module and both of the webapps.

Hth,

Nick Stolwijk
~Java Developer~

Iprofs BV.
Claus Sluterweg 125
2012 WS Haarlem
www.iprofs.nl



On Thu, Nov 13, 2008 at 7:23 PM, Wayne Fay <wa...@gmail.com> wrote:
>> Is there any way to set up multi-module projects so that they can share a
>> module, and both projects can detect when that module's source code is
>> out-of-date? Thanks,
>
> Well this is the first obvious approach:
>> \- Simple Parent Project
>>   +- Simple Weather API
>>   +- Simple Web Application Project
>>   +- Simple Web Application Project 2
>
> or this:
> \- Shared parent project
>> +- Simple Parent Project
>>   -- Simple Weather API
>>   -- Simple Web Application Project
>> +- Simple Parent Project 2
>>   -- Simple Web Application Project 2
>
> Or you could use a "builder pom" that some people advocate, which
> looks something like:
> \- builder pom (modules "..\parent1" and "..\parent2")
> \- Simple Parent Project
>  +- Simple Weather API
>  +- Simple Web Application Project
> \- Simple Parent Project 2
>  +- Simple Web Application Project 2
>
> One note, I personally do not like/use the third approach myself. I
> would tend towards the first one if you require both projects to
> "detect when a shared module is out-of-date" as you have stated. The
> fact that the projects are "completely independent" is not
> particularly important IMO.
>
> Another option would be to simply break the API out as its own
> project. Then changes would be "detected" by no one, and you would
> have to forcibly update/rebuild the webapps on an as-needed basis.
>
> Wayne
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Sharing modules among multi-module projects

Posted by Wayne Fay <wa...@gmail.com>.
> Is there any way to set up multi-module projects so that they can share a
> module, and both projects can detect when that module's source code is
> out-of-date? Thanks,

Well this is the first obvious approach:
> \- Simple Parent Project
>   +- Simple Weather API
>   +- Simple Web Application Project
>   +- Simple Web Application Project 2

or this:
\- Shared parent project
> +- Simple Parent Project
>   -- Simple Weather API
>   -- Simple Web Application Project
> +- Simple Parent Project 2
>   -- Simple Web Application Project 2

Or you could use a "builder pom" that some people advocate, which
looks something like:
\- builder pom (modules "..\parent1" and "..\parent2")
\- Simple Parent Project
  +- Simple Weather API
  +- Simple Web Application Project
\- Simple Parent Project 2
  +- Simple Web Application Project 2

One note, I personally do not like/use the third approach myself. I
would tend towards the first one if you require both projects to
"detect when a shared module is out-of-date" as you have stated. The
fact that the projects are "completely independent" is not
particularly important IMO.

Another option would be to simply break the API out as its own
project. Then changes would be "detected" by no one, and you would
have to forcibly update/rebuild the webapps on an as-needed basis.

Wayne

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org