(I apologize for cross posting this to the users and developers lists but it seemed like the right thing to do to spread this info.)
So in the end technically there was no bug however the default behavior was different than what I was expecting. I agree about preserving default behavior but there might be some things that could be done to improve or augment default behavior. In the meantime, here is a list of settings that need to be altered from their default to provide the behavior that I needed. These settings will give you the Maven experience. This I believe is a very important experience that should be easily attained. I had to debug to figure this out, but in the end Ivy was totally able to provide the desired behavior and still be Ivy. 1. Use dedicated caches per resolver (or at the very least a dedicated cache for the local filesystem resolver). Otherwise, Ivy will not distinguish between local and remote artifacts in the cache and may arbitrarily substitute one for the other. 2. Set defaultLatestStrategy="latest.time" in the settings element. Otherwise Ivy will use only alphanumeric sort when selecting between artifacts of the same version in different repositories. This is not useful at all when trying to pick up the latest integration build. The result is that you will get the first one found or the last one found based upon other configuration elements. 3. Set the property ivy.resolver.default.check.modified="true" so that Ivy does not falsely assume that an artifact never changes. 4. Set changingPattern=".*" on all resolvers so that Ivy will not exclude certain (by default all) revisions from being checked for modifications. In other words, the checkModified setting has no effect until you provide a pattern that matches the version number of the artifacts that are being resolved. 5. Use the force="true" attribute on a resolver if you wish to have it considered even after an artifact has been located by a previous resolver in the chain. This is fine tuning behavior for a build and the default is ok, but the behavior must be understood clearly as documented here. Generally speaking, without using this attribute (or setting it to false), and assuming that you use your internal resolver to publish local dev builds, listing your internal resolver first in your chain will always get you a locally published artifact even if there is a newer one in the Nexus repository. Setting this to true on a subsequent Nexus (url) resolver will select the newer of your local artifact (if present) and the Nexus artifact (if present). Not using this when publishing to your local repository means that you will have to delete your local repository when you want to pull an artifact from Nexus again. The opposite holds true - if you set force="true" on the Nexus (url) repository then you do not need to torch your local repository to get newer artifacts, but you may get newer artifacts when you least expect it if something somewhere else is publishing to Nexus. The last item (force attribute) is a very useful feature once you understand what how it behaves. What it means is, "force the artifact found by this resolver to be compared using the latestStretegy, even if a previous resolver has found an artifact of this name and version". Just keep in mind that not setting changing pattern and/or not setting checkModified are enough to abort the process such that subsequent artifact even if found, will not be considered. I really hope this helps users coming from the Maven world understand how to get the Maven experience from Ivy. And with that out of the way, users can then begin to leverage other Ivy features. Ivy provides the ability to do things that Maven just can't do, and with language besides just Java. That is huge and guarantees that Ivy will be around for a very long time. L.K. From: Loren Kratzke Sent: Friday, March 20, 2015 3:12 PM To: 'ivy-user@ant.apache.org' Subject: cache busting and integration question I am encountering challenges with the Ivy cache and also with setting up what I would consider to be a typical (if not classic) developer workflow. Here is the desired workflow: I have a Nexus repository (releases and snapshots) plus a local file system repository used for local development. I have Project which depends upon Library. I wish to modify Library, publish locally, and then pull it into the local build of Project. And for my Jenkins "continuous" integration server, if the copy of Library-1.0.0-SNAPSHOT in Nexus is newer than what is in the cache on the build machine, then I would like Ivy to grab the newer version (just like Maven does). ISSUE #1 Assuming I start with an empty cache and empty internal repo on my local dev machine, I build Project and it pulls Library from Nexus. Perfect. Works great. But then if I publish Library locally and build Project again, I will get the cached version of Library that came from Nexus. No matter what I do, I will always get the cached copy. This happens even though my chain resolver specifies my internal repo before the Nexus repo. If I blow away the cache, then I get my locally published build, but only if I blow away the cache. Otherwise I get stale stuff. Issue #2 below is all about stale stuff. I debugged Ivy (for hours upon hours) and during the resolve, it checks my internal repo, finds the fresh artifact (yay!) and the next thing it does is checks its cache, finds a module descriptor that points at Nexus, and proceeds to pull in the wrong artifact into Project. The behavior is either a bug, or implies that Ivy assumes that an artifact can only come from one place, and if it came from there once, it will come from there forever, and will never change. Again, Ivy finds the artifact in local repo, stops searching, then ends up delivering the cached artifact that came from Nexus sometime earlier. ISSUE #2 I have been working on this problem for quite some time and I thought I had it fixed, but I don't. That is, my integration server needs the latest snapshot build of Library-1.0.0-SNAPSHOT. But what I get is the cached version from the Ivy cache. An SVN commit happens, triggers a build of Library, Library get published, triggers a build of Project, and a stale build of Library is delivered to Project from the cache (which breaks Project build). SUMMARY Ivy will resolve and cache deps, but once a dep is in the cache, that's what I get forever until I blow away the cache. I see this question asked quite often regarding obtaining latest integration versions, and I see that Ivy claims to support the local development workflow, but I have yet to see a working example of either of these. Surely some of you have solved these issues. Is there any place anywhere in the world that has an example of development workflow configuration and/or integration configuration? Can anybody provide an example? So far I have not found anything, and advice on the net seems to be general suggestions like "try this, try that" and nobody really has the configuration solution. Is Ivy capable of these behaviors or do I need to hand roll a dependency management solution. Maven is too strict for these projects (C++ code). Ivy is good if I can just obtain these fundamental behaviors. Note that I have not provided any configs in this message that demonstrate the issues I am having but definitely can upon request. Thanks in advance, L.K.