Here are the projects that I am using to test and debug this situation. Each
project uses identical build.xml and settings.xml. They differ only by their
ivy.xml files. Here is the project layout:
ivy_stale_app
- build.xml
- ivy.xml
- ivysettings.xml
ivy_stale_dep
- build.xml
- ivy.xml
- ivysettings.xml
If you create the projects above using the files below, and edit such that you
can publish/retrieve from a Nexus server somewhere, then you can reproduce this
issue.
The dep project creates a file named date_time.txt with the date and time,
creates an artifact named mydep-1.0.0-SNAPSHOT from that file, and publishes
it. The app project consumes that dependency (and generates a similar but
otherwise useless artifact that can be ignored here). Monitor the date/time
value in ivy_stale_app/lib/mydep-1.0.0-SNAPSHOT in the app project to know
if/when you pick up a fresh artifact.
Here is the messed up behavior with this setup:
1. If you publish the dep to Nexus (over and over) you will get the fresh
artifact in the app every time. (GOOD)
2. If you then publish to the internal repo, you will get the cached Nexus
artifact the first time. (BAD)
3. If you publish to the internal repo a second time, you will get the internal
repo artifact. (GOOD after BAD)
4. If you publish to the internal repo over and over, you will get fresh
artifacts in the app every time. (GOOD)
5. If you publish to Nexus any time after publishing to internal, you get the
internal artifact. (regardless of the "force" attribute value)
The "force" setting on the internal repo had no effect one way or the other in
my testing with the settings below. All other setting changes have only random
and degrading effect from the above description (such as never getting anything
fresh from anywhere ever).
If I could fix #2 above I could live with Ivy. But I can't tell my customers to
be sure to build twice if developing locally. I just can't do that.
So given all of that info, and the repo steps, and the files, please anybody
show me what I am doing wrong, or agree that this is odd and undesirable
behavior that should be fixed, or tell me that Ivy just can't do what I want it
to do.
*** BEGIN build.xml ***
<project name="ivy_stale_app" xmlns:ivy="antlib:org.apache.ivy.ant">
<description>Cache test - consumer</description>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<taskdef resource="org/apache/ivy/ant/antlib.xml"/>
<ivy:settings file="ivysettings.xml"/>
<tstamp>
<format property="date_time" pattern="yyyy-MM-dd_HH:mm:ss"/>
</tstamp>
<property name="build.version" value="1.0.0-SNAPSHOT"/>
<target name="clean" description="Clean the project">
<delete dir="build"/>
<delete dir="dist"/>
<delete dir="lib"/>
</target>
<target name="retrieve" description="Fetch dependencies">
<ivy:resolve/>
<ivy:retrieve pattern="lib/[artifact]-[revision](-[classifier]).[ext]"/>
</target>
<target name="build" depends="clean,retrieve" description="build the
project">
<mkdir dir="build"/>
<echo message="${date_time}" file="build/date_time.txt"/>
</target>
<target name="dist" depends="build" description="create dist that can be
published">
<mkdir dir="dist"/>
<copy file="build/date_time.txt"
tofile="dist/${ivy.module}-${build.version}.txt"/>
</target>
<target name="preparePublish" depends="dist" description="Prepare for
publish">
<ivy:deliver deliverpattern="dist/ivy-${build.version}.xml"
pubrevision="${build.version}"
status="integration"/>
<ivy:makepom ivyfile="dist/ivy-${build.version}.xml"
pomfile="dist/${ivy.module}-${build.version}.pom"/>
</target>
<target name="publish-local" depends="preparePublish" description="Publish
artifacts locally">
<ivy:publish
artifactspattern="dist/[artifact]-${build.version}(-[classifier]).[ext]"
resolver="internal"
pubrevision="${build.version}"
status="integration"
overwrite="true"/>
</target>
<target name="publish-nexus" depends="preparePublish" description="Publish
artifacts to Nexus">
<ivy:publish
artifactspattern="dist/[artifact]-${build.version}(-[classifier]).[ext]"
resolver="nexus-snapshots-noplatform"
pubrevision="${build.version}"
status="integration"
overwrite="true"/>
</target>
</project>
*** END build.xml ***
*** BEGIN ivysettings.xml ***
<ivysettings>
<caches defaultCacheDir="${user.home}/.ivy2/cache"/>
<settings defaultResolver="chain"/>
<credentials host="nexus.mycompany.com" realm="Sonatype Nexus Repository
Manager" username="name" passwd="pass"/>
<property name="m2pattern"
value="[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"/>
<property name="internal.repo.dir" value="${user.home}/.ivy2/m2"/>
<property name="mycompany.repo.url"
value="http://nexus.mycompany.com:8081/nexus/content/repositories"/>
<!--<property name="ivy.resolver.default.check.modified" value="true"/>-->
<resolvers>
<filesystem name="internal" force="true" checkmodified="true"
changingPattern=".*">
<ivy pattern="${internal.repo.dir}/[module]/ivy-[revision].xml" />
<artifact pattern="${internal.repo.dir}/${m2pattern}" />
</filesystem>
<url name="nexus-snapshots-noplatform" m2compatible="true"
checkmodified="true" changingPattern=".*">
<artifact pattern="${mycompany.repo.url}/snapshots/${m2pattern}" />
</url>
<chain name="chain" checkmodified="true" changingPattern=".*">
<resolver ref="internal"/>
<resolver ref="nexus-snapshots-noplatform"/>
</chain>
</resolvers>
</ivysettings>
*** END ivysettings.xml ***
*** BEGIN ivy.xml for dependency project ***
<?xml version="1.0" encoding="utf-8"?>
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="example.scratch" module="mydep"/>
<publications>
<artifact name="mydep" type="pom"/>
<artifact name="mydep" type="txt"/>
</publications>
</ivy-module>
*** END ivy.xml for dependency project ***
*** BEGIN ivy.xml for consumer of dependency ***
<?xml version="1.0" encoding="utf-8"?>
<ivy-module version="2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd"
xmlns:m="http://ant.apache.org/ivy/maven">
<info organisation="example.scratch" module="myapp"/>
<publications>
<artifact name="myapp" type="pom"/>
<artifact name="myapp" type="txt"/>
</publications>
<dependencies>
<dependency org="example.scratch" name="mydep" rev="1.0.0-SNAPSHOT">
<artifact name="mydep" type="txt"/>
</dependency>
</dependencies>
</ivy-module>
*** END ivy.xml for consumer of dependency ***
L.K.
-----Original Message-----
From: Zac Jacobson [mailto:[email protected]]
Sent: Sunday, March 22, 2015 6:07 PM
To: [email protected]
Subject: Re: cache busting and integration question
If you set your resolver’s checkmodified flag to true, it will verify the
timestamp of the published artifact and pull down a more recent version if the
repo is newer than the cache. I’ve found that if you have chained resolvers,
you need to do this at the top level and it affects all repos, not just your
snapshot repository.
Also, if you set the force attribute for your local resolver, it will always
take a version from there rather than going to other resolvers in the chain.
Once you’ve got changes published to your snapshot or release repo, you’ll want
to clean that artifact out of your local repo.