You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ivy-user@ant.apache.org by Gareth Western <ga...@garethwestern.com> on 2009/07/10 15:54:48 UTC

Multi-module dependency configuration

Hi,

I'm having trouble configuring a multi-module project. It's a
straightforward scenario, but I can't seem to get the syntax quite
right. Here's the situation:

Module A is a webapp, producing a .war artifact, and has a dependency
on module B, which produces a jar. Both modules have a dependency on a
third-party jar, which is provided by the servlet container at runtime
and I therefore do not want included in the module A war file.

The module B (the jar module) configuration looks like this:

<ivy-module version="2.0">
  <info organisation="com.garethwestern" module="B"/>
  <configurations>
    <conf name="compile" extends="jar" />
    <conf name="jar" />
  </configurations>
  <publications>
    <artifact type="jar" conf="jar" />
  </publications>
  <dependencies>
    <dependency org="j2ee" name="j2ee" rev="1.3.1"
conf="compile->default" /> <!-- this is the "provided" jar -->
    <dependency org="commons-beanutils" name="commons-beanutils"
rev="1.7.0" conf="jar->default" />
  </dependencies>
</ivy-module>


The module A configuration looks like this:

<ivy-module version="2.0">
  <info organisation="com.garethwestern" module="A" />
  <configurations>
    <conf name="compile" extends="war"/>
    <conf name="war" />
  </configurations>
  <publications>
    <artifact name="myModule" type="war" conf="war"/>
  </publications>
  <dependencies>
    <dependency org="j2ee" name="j2ee" rev="1.3.1"
conf="compile->default"/> <!-- provided jar again -->
    <dependency org="com.garethwestern" name="B" rev="SNAPSHOT"
changing="true" conf="compile->jar" />
  </dependencies>
</ivy-module>

In the Ant script for module A I use the cachepath task to create the
classpath for compiling the module:
    <ivy:cachepath pathid="classpath" conf="compile" />

Then, when I construct the war file, I use the cachefileset task to
create a fileset for all files to be copied to WEB-INF/lib inside the
war:
    <ivy:cachefileset setid="webinf-lib" conf="war" />

The problem is that the com.garethwestern.B dependency is specified
with the "compile->jar configuration" meaning that it will not be
included in the webinf-lib fileset (which uses the "war" configuration
to avoid including the j2ee.jar). If i change the B dependency to
conf="war->jar" then compilation fails because the classpath is
configured using the "compile" configuration. I thought that maybe a
conf such as *->jar might work, but that seems to just have the same
affect as war->jar...

I'm sure that what I'm trying to achieve is incredibly simple, but
after reading through the Ivy documentation and looking through
various examples online my head's in a muddle at the moment, and so
I've resorted to the mailing list. Can anyone out there help me?

Thanks,

Gareth

Re: Multi-module dependency configuration

Posted by Pavel Sharov <ps...@optima.com.ua>.
Gareth,

in your modules I see in particular the following chain of transitive
dependencies: webapp depends on lookups; if you resolve webapps
against "war" configuration (implicitly, by making ivy:cachefileset as
far as I understand), then, according to mapping, lookup resolves in
"war" as well; lookup in turn depends in "war" conf on
authentication's "compile" conf ("war->compile"); and authentication
finally depends in "compile" conf on j2ee, hence it's included, which
is not what you want, is it? I don't know if you can change lookups
depend on authentication like "war->jar" instead of "war->compile",
anyway this could be the reason, as it seems to me. Sorry if I took it
wrong when trying to interpret which modules correspond to A, B and C
in your previous posts...

-Pavel

Sunday, July 12, 2009, 7:56:26 PM, you wrote:

GW> Yep, sure thing Pavel. Here's a zip containing the ivy.xmls (actually
GW> 6 modules, not 5, sorry), and a brief description of each module:

GW> Authentication produces a jar.
GW> Business-tier produces two different jars (a main one, and a trimmed
GW> version), however the webapp only requires the main one.
GW> Lookups is actually another webapp which results in a war file,
GW> however the webapp is dependent on some of the classes from this
GW> module too. My plan is to expand the lookups war into the exploded
GW> directory of the main webapp prior to creating the webapp war.
GW> Presentation-tier produces both a jar and a zip. The webapp is
GW> dependent on the jar.
GW> Utilities produces a jar.
GW> Finally, the webapp produces the main application's war!

GW> It's a bit of a confusing layout. It's all a legacy system which I'm
GW> trying to improve by at least sorting out the dependency management,
GW> as we don't currently have a very good idea of how it's all related :\

GW> Thanks again for your help!





Re: Multi-module dependency configuration

Posted by Gareth Western <ga...@garethwestern.com>.
Yep, sure thing Pavel. Here's a zip containing the ivy.xmls (actually
6 modules, not 5, sorry), and a brief description of each module:

Authentication produces a jar.
Business-tier produces two different jars (a main one, and a trimmed
version), however the webapp only requires the main one.
Lookups is actually another webapp which results in a war file,
however the webapp is dependent on some of the classes from this
module too. My plan is to expand the lookups war into the exploded
directory of the main webapp prior to creating the webapp war.
Presentation-tier produces both a jar and a zip. The webapp is
dependent on the jar.
Utilities produces a jar.
Finally, the webapp produces the main application's war!

It's a bit of a confusing layout. It's all a legacy system which I'm
trying to improve by at least sorting out the dependency management,
as we don't currently have a very good idea of how it's all related :\

Thanks again for your help!


On Fri, Jul 10, 2009 at 9:49 PM, Pavel Sharov<ps...@optima.com.ua> wrote:
> Gareth,
>
> could you then provide the complete ivy.xml info on all your 5 modules?
>
> -Pavel
>
> Friday, July 10, 2009, 9:37:22 PM, you wrote:
>
> GW> Hmmm, so it appears that when module A (the webapp) declares module B
> GW> (jar) as a dependency then then j2ee.jar (B's dependency) is not
> GW> included. However when I also declare module C (another jar, which is
> GW> also dependent on both module B and the j2ee.jar) as a dependency of A
> GW> then the j2ee.jar starts to get included in A (presumably as a
> GW> transitive depdency, somehow?). But I still don't understand why,
> GW> because A declares both B and C dependencies with
> conf="war->>jar;compile->compile" and the j2ee.jar is always listed in
> GW> every ivy.xml with conf="compile->default", which I thought would mean
> GW> it shouldn't be included when using the "war" configuration?
>
> GW> Sorry if i'm not making much sense. I've been looking at this for too long!
>
> GW> Cheers,
>
> GW> Gareth
>
>
>
>

Re: Multi-module dependency configuration

Posted by Pavel Sharov <ps...@optima.com.ua>.
Gareth,

could you then provide the complete ivy.xml info on all your 5 modules?

-Pavel

Friday, July 10, 2009, 9:37:22 PM, you wrote:

GW> Hmmm, so it appears that when module A (the webapp) declares module B
GW> (jar) as a dependency then then j2ee.jar (B's dependency) is not
GW> included. However when I also declare module C (another jar, which is
GW> also dependent on both module B and the j2ee.jar) as a dependency of A
GW> then the j2ee.jar starts to get included in A (presumably as a
GW> transitive depdency, somehow?). But I still don't understand why,
GW> because A declares both B and C dependencies with
conf="war->>jar;compile->compile" and the j2ee.jar is always listed in
GW> every ivy.xml with conf="compile->default", which I thought would mean
GW> it shouldn't be included when using the "war" configuration?

GW> Sorry if i'm not making much sense. I've been looking at this for too long!

GW> Cheers,

GW> Gareth




RE: Multi-module dependency configuration

Posted by Alex Zhukov <al...@hotmail.com>.

>>>But I still don't understand why, because A declares both B and C ...

try to run it in debug mode: ant -d your_target_name
it may give you some clue.

Aleksey 

> Date: Fri, 10 Jul 2009 19:37:22 +0100
> Subject: Re: Multi-module dependency configuration
> From: gareth@garethwestern.com
> To: ivy-user@ant.apache.org
> 
> Hmmm, so it appears that when module A (the webapp) declares module B
> (jar) as a dependency then then j2ee.jar (B's dependency) is not
> included. However when I also declare module C (another jar, which is
> also dependent on both module B and the j2ee.jar) as a dependency of A
> then the j2ee.jar starts to get included in A (presumably as a
> transitive depdency, somehow?). But I still don't understand why,
> because A declares both B and C dependencies with
> conf="war->jar;compile->compile" and the j2ee.jar is always listed in
> every ivy.xml with conf="compile->default", which I thought would mean
> it shouldn't be included when using the "war" configuration?
> 
> Sorry if i'm not making much sense. I've been looking at this for too long!
> 
> Cheers,
> 
> Gareth
> 
> On Fri, Jul 10, 2009 at 7:23 PM, Gareth Western<ga...@garethwestern.com> wrote:
> >
> > So now the webapp compiles, however the "compile-time-only" jar is
> > still being brought into the webapp's WEB-INF/lib folder somehow. If I
> > use Ivy to generate a dependency report, it says that the jar is
> > required by 3 of the other modules, however in the ivy file for each
> > of those modules the j2ee.jar is specified with
> > conf="compile->default":
> >    <dependency org="j2ee" name="j2ee" rev="1.3.1" conf="compile->default"/>
> > so I don't see how it could be being involved in the "war"
> > configuration from the webapp module.
> >
> > I'm not sure how to explain the whole scenario without attaching all
> > the files involved (there are 5 modules in total, each with a
> > build.xml and ivy.xml). Does anyone have any tips for how to track
> > down exactly what's happening?
> >

_________________________________________________________________
Windows Live™ Photos: it's easy to store and manage your photos online. See how.
http://windowslive.com/Online/Photos?ocid=TXT_TAGLM_WL_CS_PH_store_manage_072009

Re: Multi-module dependency configuration

Posted by Gareth Western <ga...@garethwestern.com>.
Hmmm, so it appears that when module A (the webapp) declares module B
(jar) as a dependency then then j2ee.jar (B's dependency) is not
included. However when I also declare module C (another jar, which is
also dependent on both module B and the j2ee.jar) as a dependency of A
then the j2ee.jar starts to get included in A (presumably as a
transitive depdency, somehow?). But I still don't understand why,
because A declares both B and C dependencies with
conf="war->jar;compile->compile" and the j2ee.jar is always listed in
every ivy.xml with conf="compile->default", which I thought would mean
it shouldn't be included when using the "war" configuration?

Sorry if i'm not making much sense. I've been looking at this for too long!

Cheers,

Gareth

On Fri, Jul 10, 2009 at 7:23 PM, Gareth Western<ga...@garethwestern.com> wrote:
>
> So now the webapp compiles, however the "compile-time-only" jar is
> still being brought into the webapp's WEB-INF/lib folder somehow. If I
> use Ivy to generate a dependency report, it says that the jar is
> required by 3 of the other modules, however in the ivy file for each
> of those modules the j2ee.jar is specified with
> conf="compile->default":
>    <dependency org="j2ee" name="j2ee" rev="1.3.1" conf="compile->default"/>
> so I don't see how it could be being involved in the "war"
> configuration from the webapp module.
>
> I'm not sure how to explain the whole scenario without attaching all
> the files involved (there are 5 modules in total, each with a
> build.xml and ivy.xml). Does anyone have any tips for how to track
> down exactly what's happening?
>

Re: Multi-module dependency configuration

Posted by Gareth Western <ga...@garethwestern.com>.
Thank you Mitch, Pavel, and Alex for your answers. Based on what
you've all said I don't think I'm actually doing anything wrong, so
it's more likely to be a simple misconfiguration rather than a
misconception as to how Ivy works.

Mitch: I like your suggestion as to how to improve the syntax for the
dependency configuration, and I've updated my ivy files accordingly.

Pavel: yes, the compilation fails, but I misread the compilation
output and it was a different module ("C") which was failing, rather
than "B" in my (oversimplified) example. Correcting the dependency
syntax as Mitch suggested helped me to identify this.

Aleksey: Yes, your situation sounds very similar to mine, although I'm
not using the same commands (e.g. cachefileset rather than
resolve/retrieve). If I don't manage to fix my problems then I'll
probably try to adopt the exact same syntax as you say you're using.

So now the webapp compiles, however the "compile-time-only" jar is
still being brought into the webapp's WEB-INF/lib folder somehow. If I
use Ivy to generate a dependency report, it says that the jar is
required by 3 of the other modules, however in the ivy file for each
of those modules the j2ee.jar is specified with
conf="compile->default":
    <dependency org="j2ee" name="j2ee" rev="1.3.1" conf="compile->default"/>
so I don't see how it could be being involved in the "war"
configuration from the webapp module.

I'm not sure how to explain the whole scenario without attaching all
the files involved (there are 5 modules in total, each with a
build.xml and ivy.xml). Does anyone have any tips for how to track
down exactly what's happening?

RE: Multi-module dependency configuration

Posted by Alex Zhukov <al...@hotmail.com>.


Gareth,



>>>I'm sure that what I'm trying to achieve is
incredibly simple, but …

Well, I agree it should be incredibly simple, but it is not. :)




I was facing the similar problem and that is how I solved it.

First of all, all my ivy files have configurations as follow:

  <configurations>

    <conf name='default' description='Default configuration
used when nothing is specified'/>

    <conf name='deploy' extends='default' description='Deps
which are available in the build classpath.'/>

    <conf name='compile' extends='deploy'
description='Compile time deps, including deploy deps.'/>

    <conf name='run' extends='deploy' description='Dependencies
required at runtime, including deploy.'/>

    <conf name='test' extends='default' description='Test
deps are only available in the test classpath.'/>

  </configurations>



as you can see I have separated configurations for deps for run time, test, compile
and deploy. Having that, I can define the dependencies how I want. Most of the
time I use 'deploy' configuration for my deps, but if I need to specify an
artifact that I need for the compilation but do not need to include it into war
file, I use 'compile' configuration and vice versa if I need an artifact to be
included into war, but I do not need it at 'compile' time I define it at 'run'
configuration. I hope you got it. (As for the situation where I need an
artifact for both test and compile time I use ‘default’ configuration)



Now, the interesting part is that how you resolve the artifacts. When I compile
my artifact I use <ivy:resolve conf='compile' ...> <ivy:retrive
conf="compile" ...>, but when I build my war I use <ivy:resolve
conf="run" ...> <ivy:retrive conf="run" ...>.
Again, I hope it makes sense. 



This all above works like a charm, but the problem is how you would put things
together at the resolution time. Let’s take for example of A depending on B. ‘A’
may have ‘run’ dependencies, but B may not. When you build (not compile) A’s
war you will not get B’s dependencies artifacts, unless you explicitly define
them with conf=’run’. (I am not may be clear about the exact resolution hurdles and it is not a point her,
but if you try you will see the problems). So, how to fix that?  :) 

And now the trickiest part ever. You should define your
dependency for all modules as:

<dependencies
defaultconfmapping="*->@(default)">

     <dependency …/>

</dependencies>

 

If you need additional help, just ask.

 

Aleksey 



> Date: Fri, 10 Jul 2009 14:54:48 +0100
> Subject: Multi-module dependency configuration
> From: gareth@garethwestern.com
> To: ivy-user@ant.apache.org
> 
> Hi,
> 
> I'm having trouble configuring a multi-module project. It's a
> straightforward scenario, but I can't seem to get the syntax quite
> right. Here's the situation:
> 
> Module A is a webapp, producing a .war artifact, and has a dependency
> on module B, which produces a jar. Both modules have a dependency on a
> third-party jar, which is provided by the servlet container at runtime
> and I therefore do not want included in the module A war file.
> 
> The module B (the jar module) configuration looks like this:
> 
> <ivy-module version="2.0">
>   <info organisation="com.garethwestern" module="B"/>
>   <configurations>
>     <conf name="compile" extends="jar" />
>     <conf name="jar" />
>   </configurations>
>   <publications>
>     <artifact type="jar" conf="jar" />
>   </publications>
>   <dependencies>
>     <dependency org="j2ee" name="j2ee" rev="1.3.1"
> conf="compile->default" /> <!-- this is the "provided" jar -->
>     <dependency org="commons-beanutils" name="commons-beanutils"
> rev="1.7.0" conf="jar->default" />
>   </dependencies>
> </ivy-module>
> 
> 
> The module A configuration looks like this:
> 
> <ivy-module version="2.0">
>   <info organisation="com.garethwestern" module="A" />
>   <configurations>
>     <conf name="compile" extends="war"/>
>     <conf name="war" />
>   </configurations>
>   <publications>
>     <artifact name="myModule" type="war" conf="war"/>
>   </publications>
>   <dependencies>
>     <dependency org="j2ee" name="j2ee" rev="1.3.1"
> conf="compile->default"/> <!-- provided jar again -->
>     <dependency org="com.garethwestern" name="B" rev="SNAPSHOT"
> changing="true" conf="compile->jar" />
>   </dependencies>
> </ivy-module>
> 
> In the Ant script for module A I use the cachepath task to create the
> classpath for compiling the module:
>     <ivy:cachepath pathid="classpath" conf="compile" />
> 
> Then, when I construct the war file, I use the cachefileset task to
> create a fileset for all files to be copied to WEB-INF/lib inside the
> war:
>     <ivy:cachefileset setid="webinf-lib" conf="war" />
> 
> The problem is that the com.garethwestern.B dependency is specified
> with the "compile->jar configuration" meaning that it will not be
> included in the webinf-lib fileset (which uses the "war" configuration
> to avoid including the j2ee.jar). If i change the B dependency to
> conf="war->jar" then compilation fails because the classpath is
> configured using the "compile" configuration. I thought that maybe a
> conf such as *->jar might work, but that seems to just have the same
> affect as war->jar...
> 
> I'm sure that what I'm trying to achieve is incredibly simple, but
> after reading through the Ivy documentation and looking through
> various examples online my head's in a muddle at the moment, and so
> I've resorted to the mailing list. Can anyone out there help me?
> 
> Thanks,
> 
> Gareth

_________________________________________________________________
Hotmail® has ever-growing storage! Don’t worry about storage limits. 
http://windowslive.com/Tutorial/Hotmail/Storage?ocid=TXT_TAGLM_WL_HM_Tutorial_Storage_062009

Re: Multi-module dependency configuration

Posted by Mitch Gitman <mg...@gmail.com>.
Gareth, I haven't fully digested you situation, but a sensible way to
organize the confs would be to have your webapp's dependency on your library
look something like so:
   <dependency org="com.garethwestern" name="B" rev="SNAPSHOT"
changing="true" conf="war->jar;compile->compile" />

Here, you're clearly separating the chain of dependencies for compilation
from the chain of dependencies for packaging.

On Fri, Jul 10, 2009 at 6:54 AM, Gareth Western <ga...@garethwestern.com>wrote:

> Hi,
>
> I'm having trouble configuring a multi-module project. It's a
> straightforward scenario, but I can't seem to get the syntax quite
> right. Here's the situation:
>
> Module A is a webapp, producing a .war artifact, and has a dependency
> on module B, which produces a jar. Both modules have a dependency on a
> third-party jar, which is provided by the servlet container at runtime
> and I therefore do not want included in the module A war file.
>
> The module B (the jar module) configuration looks like this:
>
> <ivy-module version="2.0">
>  <info organisation="com.garethwestern" module="B"/>
>  <configurations>
>    <conf name="compile" extends="jar" />
>    <conf name="jar" />
>  </configurations>
>  <publications>
>    <artifact type="jar" conf="jar" />
>  </publications>
>  <dependencies>
>    <dependency org="j2ee" name="j2ee" rev="1.3.1"
> conf="compile->default" /> <!-- this is the "provided" jar -->
>    <dependency org="commons-beanutils" name="commons-beanutils"
> rev="1.7.0" conf="jar->default" />
>  </dependencies>
> </ivy-module>
>
>
> The module A configuration looks like this:
>
> <ivy-module version="2.0">
>  <info organisation="com.garethwestern" module="A" />
>  <configurations>
>    <conf name="compile" extends="war"/>
>    <conf name="war" />
>  </configurations>
>  <publications>
>    <artifact name="myModule" type="war" conf="war"/>
>  </publications>
>  <dependencies>
>    <dependency org="j2ee" name="j2ee" rev="1.3.1"
> conf="compile->default"/> <!-- provided jar again -->
>    <dependency org="com.garethwestern" name="B" rev="SNAPSHOT"
> changing="true" conf="compile->jar" />
>  </dependencies>
> </ivy-module>
>
> In the Ant script for module A I use the cachepath task to create the
> classpath for compiling the module:
>    <ivy:cachepath pathid="classpath" conf="compile" />
>
> Then, when I construct the war file, I use the cachefileset task to
> create a fileset for all files to be copied to WEB-INF/lib inside the
> war:
>    <ivy:cachefileset setid="webinf-lib" conf="war" />
>
> The problem is that the com.garethwestern.B dependency is specified
> with the "compile->jar configuration" meaning that it will not be
> included in the webinf-lib fileset (which uses the "war" configuration
> to avoid including the j2ee.jar). If i change the B dependency to
> conf="war->jar" then compilation fails because the classpath is
> configured using the "compile" configuration. I thought that maybe a
> conf such as *->jar might work, but that seems to just have the same
> affect as war->jar...
>
> I'm sure that what I'm trying to achieve is incredibly simple, but
> after reading through the Ivy documentation and looking through
> various examples online my head's in a muddle at the moment, and so
> I've resorted to the mailing list. Can anyone out there help me?
>
> Thanks,
>
> Gareth
>

Re: Multi-module dependency configuration

Posted by Pavel Sharov <ps...@optima.com.ua>.
Gareth,

> If i change the B dependency to conf="war->jar" then compilation
> fails because the classpath is configured using the "compile"
> configuration.

Are you sure compilation fails in this case? If your compilation uses
resolving against "compile" conf, then it should include dependencies
declared in a parent conf, which is "war" in your case...

-Pavel