tags:

views:

396

answers:

2

I've been using Ivy a bit but I seem to still have a lot to learn.

I have two projects. One is a web app and the other is a library upon which the web app depends. The set up is that the library project is compiled to a jar file and published using Ivy to a directory within the project. In the web app build file, I have an ant target that calls the Ivy resolve ant task.

What I'd like to do is have the web app using the dynamic resolve mode during development (on developer's local machines) and default resolve mode for test and production builds. Previously I was appending a time stamp to the library archive file so that Ivy would notice changes in file when the web app tried to resolve its dependency on it. Within Eclipse this is cumbersome because, in the web app, the project had to be refreshed and the build path tweaked every time a new library jar was published. Publishing a similarly named jar file every time would, I figure, only require developers to refresh the project.

The problem is that the web app is unable to retrieve the dynamic jar file.

The output I get looks something like this:

resolve:
[ivy:configure] :: Ivy 2.1.0 - 20090925235825 :: http://ant.apache.org/ivy/ ::
[ivy:configure] :: loading settings :: file = /Users/richard/workspace/webapp/web/WEB-INF/config/ivy/ivysettings.xml
[ivy:resolve] :: resolving dependencies :: com.webapp#webapp;[email protected]
[ivy:resolve]   confs: [default]
[ivy:resolve]   found com.webapp#library;latest.integration in local
[ivy:resolve] :: resolution report :: resolve 142ms :: artifacts dl 0ms
---------------------------------------------------------------------
|                  |            modules            ||   artifacts   |
|       conf       | number| search|dwnlded|evicted|| number|dwnlded|
---------------------------------------------------------------------
|      default     |   1   |   0   |   0   |   0   ||   0   |   0   |
---------------------------------------------------------------------
[ivy:resolve] 
[ivy:resolve] :: problems summary ::
[ivy:resolve] :::: WARNINGS
[ivy:resolve]       ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve]       ::          UNRESOLVED DEPENDENCIES         ::
[ivy:resolve]       ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve]       :: com.webapp#library;latest.integration: impossible to resolve dynamic revision
[ivy:resolve]       ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:resolve] :::: ERRORS
[ivy:resolve]   impossible to resolve dynamic revision for com.webapp#library;latest.integration: check your configuration and make sure revision is part of your pattern
[ivy:resolve] 
[ivy:resolve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS

BUILD FAILED 
/Users/richard/workspace/webapp/build.xml:71: impossible to resolve dependencies:
resolve failed - see output for details

The web app resolve target looks like this:

<target name="resolve" depends="load-ivy">
    <ivy:configure file="${ivy.dir}/ivysettings.xml" />

    <ivy:resolve 
        file="${ivy.dir}/ivy.xml" 
        resolveMode="${ivy.resolve.mode}"/>

    <ivy:retrieve pattern="${lib.dir}/[artifact]-[revision].[ext]" type="jar" sync="true" />
</target> 

In this case, ivy.resolve.mode has a value of 'dynamic' (without quotes).

The web app's Ivy file is simple. It looks like this:

<ivy-module version="2.0" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"&gt;

    <info organisation="com.webapp" module="webapp"/>

    <dependencies>
        <dependency name="library" rev="${ivy.revision.default}" revConstraint="${ivy.revision.dynamic}" />
    </dependencies>

</ivy-module>

During development, ivy.revision.dynamic has a value of 'latest.integration'. While, during production or test, 'ivy.revision.default' has a value of '1.0'.

Any ideas? Please let me know if there's any more information I need to supply.

Thanks!

+1  A: 

I think you need to drop use of the revConstraint attribute, in your webapp's ivy file.

Ivy thinks that "latest.revision" is the revision you want to retrieve instead of actually looking for the latest revision :-)

I'd recommend just setting the dependency as follows:

<dependency name="library" rev="latest.integration"/>

Explanation:

revConstraint is set when you publish a module. It records the latest revision at time of publication. So you don't need it during development. Nor do you need to use revision variable. When you publish an ivy module with "latest.revision" or "latest.release" revision references the get resolved and recorded in the revConstraint attribute.

See the following link for more information:

http://ant.apache.org/ivy/history/latest-milestone/ivyfile/dependency.html#revision-constraint

Mark O'Connor
Thanks, Mark, but this still doesn't solve my problem. I've changed the dependency as you indicated, varied the value of resolveMode in webapp's resolve target between 'default' and 'dynamic', and removed it altogether, and still the latest publish of the library jar is not 'picked up' by webapp. Doing some more research led me to this:http://ant.apache.org/ivy/history/latest-milestone/concept.html#changeHowever, using checkmodified on the local resolver doesn't work either. I must still not be understanding something properly.
richever
I also tried adding changingPattern to no avail:<filesystem name="local" checkmodified="true" changingPattern="dev">The library jar is named libra-dev.jar.
richever
Could you update your post with the new ivy output? Also could you please include your ivysettings file (If you're using one)
Mark O'Connor
A: 

I added the following and it seems to work. I'll caveat this with the acknowledgement that I'm also struggling with ivy and a lot of the stuff I have working is pretty much black-box working... i.e. it does the job so I stop fiddling! My understanding is somewhat less advanced I'm afraid to say.

Anwyay, in settings.xml I added:

 <modules>
     <module organisation="my.organisation" name="*" resolveMode="dynamic"/>
 </modules>

Which I think tells ivy to use its intelligence to work with these modules. That intelligence possibly includes checking of updated versions of the module at resolve time.

Also, on the resolvers I added checkModified and changingPattern. Apparnntly it's important to do this both on the actual resolver and the wrapping chain (if you have one):

<chain name="foo" checkmodified="true"  changingPattern=".*-SNAPSHOT">
    <url name="bar" checkmodified="true" changingPattern=".*-SNAPSHOT">  
       <ivy pattern=... />  
       <artifact pattern=... /> 
    </url>  
    ...
</chain>

The checkModified hopefully does what it says on the tin. And I gather that the changingPattern tells ivy to check whether artifacts containing this pattern have a new update in the repo. I'm personally using a maven repo where modifiable stuff always has -SNAPSHOT appended to it so that's why I use that (fairly common I think). I guess you could replace this changingPattern with ".*" or something that suits you better.

Uberpuppy