9 Replies Latest reply on Aug 5, 2010 12:26 PM by Paul Gier

    snapshot dependencies

    Paul Gier Master

      The question came up again on IRC yesterday about how to best handle continuous integration and whether we can use snapshot dependencies in the build.  I'd like to discuss this and hopefully come up with some best practices for AS 7.  First I will try to define the problem as I understand it, and then we can discuss how to hande it.


      Defining The Problem

      Maven uses a concept of a snapshot dependency where the most recent deployment of the artifact is downloaded from the repository.  The problem is that the specific dependency versions are not tracked in the POM in the repository.  So let's say we have three projects A, B, and C where A depends on B which depends on C.


      A:1.0-SNAPSHOT -> B:2.0-SNAPSHOT -> C:3.0-SNAPSHOT


      First, project C is built and deployed to the repository (build # 1 of C).  Next, project B is built and deployed to the repository (build # 1 of B).  B has a dependency on C:3.0-SNAPSHOT in the POM, but B is actually dependent on build number 1 of C.  Next, project A is built in the continuous integration server (Hudson) and has an failure during testing.  The real dependency tree looks like


      A:1.0-SNAPSHOT -> B:2.0-SNAPSHOT-build-1 -> C:3.0-SNAPSHOT-build-1


      Next, project C is modified and built and deploy again (build # 2 of C).  A developer of project A checks out the code and tries to reproduce the error from the Hudson build.  Instead of seeing the expected error, the developer of project A sees a new error introduced by C:3.0-SNAPSHOT-build-2.  The developer is unable to reproduce the error seen in the Hudson build, because the build no longer contains any reference to C:3.0-SNAPSHOT-build-1.  In a project with a medium to large dependency tree it is not possible/practical to track down the original dependency tree used during the Hudson build.


      Upstream Maven

      As far as I can tell the Maven project itself does not deal with this problem.  For the Maven project it seems to be uncommon that a new snapshot dependency deployment will prevent the ability to reproduce errors.  There are a few reasons why this doesn't affect the Maven project the same way as it affects the JBoss AS project:

      1. Smaller dependency tree
      2. Less frequent snapshot deployments
      3. more stable set of dependencies (slower changes)


      Possible Solutions

      1. Continue the practice of not allowing SNAPSHOTs in the dependency tree.
      2. Use normal Maven SNAPSHOTs with the risk of not being able to reproduce errors in some situations
      3. Find a way to lock snapshots to their timestamped versions during deployment
        1. Use the versions-maven-plugin to lock and unlock snapshots before deployment
        2. Always use timestamped snapshots and add something to the versions-maven-plugin to automate updating to the latest
        • 1. Re: snapshot dependencies
          Carlo de Wolf Master

          If we're going with the version plugin, then it needs to work within the current execution of mvn deploy.

          Any manual intervention is error prone.


          Right now the changes made by the version plugin need to be saved to disk first and mvn needs to be restarted.

          • 2. Re: snapshot dependencies
            Paul Gier Master

            Carlo de Wolf wrote:


            If we're going with the version plugin, then it needs to work within the current execution of mvn deploy.

            Any manual intervention is error prone.


            Right now the changes made by the version plugin need to be saved to disk first and mvn needs to be restarted.

            Currently Maven does not allow changes to the POM during the build because this would break other parts of the build process.  If this changes in the future, then goals of the versions maven plugin could be integrated into the build process.


            The other option is to use Ant (Ivy or Maven Ant Tasks) or Gradle to build and generate the POMs with resolved snapshots for deployment.

            • 3. Re: snapshot dependencies
              Jason Greene Master

              I would love to see something that is DVCS friendly, and thus does not soley use timestamps. Instead some kind of sha1, uuid, repo url, or username could be used to produce a unique deployment. In other words,  if the notion of "latest" is to exist, it needs to be per repo & branch.


              That said, I still am not sure how "latest" even matters with AS, we certainly don't use ranges today.


              I would expect the process to do this would be like so:


              1. User hacks code somewhere
              2. User commits X Y and Z
              3. They decide to push a snapshot, so they run some kind of make-snapshot command, which updates all pom info
              4. They decide to push the snapshot, and run some kind of nexus deploy or something similar (this could be merged with step 3)
              5. The user then updates dependent projects with the unique identifier generated in 3


              Any suggestions on what could do the above process? Will gradle or some ant task help us here?

              • 4. Re: snapshot dependencies
                Andrew Rubinger Master

                Jason Greene wrote:


                Any suggestions on what could do the above process? Will gradle or some ant task help us here?

                Currently I don't see any best practice for any build system which does exactly this.  Which is a bit baffling. 


                All definitions I've read on "continuous integration" really refer to integrating new code into the mainline, which assumes you have all sources in the tree.  Left out of scope is the integration of prebuilt binaries, something we're leaning heavily towards nowadays.


                Over the weekend and so far today I've been looking at Gradle and Ivy's dependency resolvers to see at which granularity we can define rules:


                1. For all org.jboss.ejb3.*, pull in the latest SNAPSHOT
                2. For all org.jboss.*, pull in the latest RELEASE
                3. For everything else, use the defined static dependencies


                ...etc.  And be able to run a variety of build configurations on the same integration project to see how external runtime upgrades affect the mainline testsuite.


                Using the ShrinkWrap project now as a prototype for seeing how this might fit together in practice.  What I really need to do is figure out how to enable *real* CI, accounting for dependencies, in EJB3.  I imagine the requirements would be very similar for AS7.


                Some related discussion from #jboss-dev:


                (02:10:08 PM) ALR: sebersole: Ping, wanna pick your brain on Gradle w.r.t. real CI.
                (02:10:36 PM) ALR: Been reading Gradle docs and examples most of the morning.
                (02:10:47 PM) sebersole: k
                (02:11:00 PM) ALR: sebersole: Here's the use case:
                (02:11:01 PM) sebersole: thats about where i stopped though
                (02:11:05 PM) ALR: Ah, OK.
                (02:11:13 PM) ALR: What I want to do is get a build which can:
                (02:11:26 PM) ALR: 1) Build against static matrix of dependencies (we have this in Maven)
                (02:11:55 PM) sebersole: no idea what "static matrix of deps" os
                (02:11:57 PM) sebersole: i
                (02:11:59 PM) sebersole: grrr
                (02:12:00 PM) sebersole: is
                (02:12:04 PM) ALR: 2) Send a switch or have an alternate build which can grab the latest *versioned* SNAPSHOT of a set of dependencies, without leaking in unversioned stuff transitively.
                (02:12:28 PM) ALR: "static matrix of deps" == longwinded way of saying "dependencies" section of POM.
                (02:12:36 PM) ALR: groupId:artifactId:version
                (02:13:06 PM) sebersole: well the general concept is the kind of thing gradle excels at
                (02:13:09 PM) lightguard_jp [~lightguar@166-70-166-98.ip.xmission.com] entered the room.
                (02:13:17 PM) sebersole: haha just in time
                (02:13:22 PM) lightguard_jp: lol
                (02:13:23 PM) ALR: I summoned.
                (02:13:26 PM) sebersole: ah
                (02:13:27 PM) lightguard_jp: ALR told me to come in
                (02:13:40 PM) ALR: Basically I hear about pluggable resolving in Gradle w/ Ivy backend
                (02:13:49 PM) ALR: What I'd like is some example of how this works in practice.
                (02:14:00 PM) ALR: So I can refine my use cases and see that everything fits.
                (02:14:02 PM) sebersole: afaik pluggable means different sources
                (02:14:07 PM) sebersole: maven repos
                (02:14:11 PM) sebersole: ivy repos
                (02:14:13 PM) sebersole: file systems
                (02:14:15 PM) sebersole: etc
                (02:14:15 PM) ALR: Well, it also means different resolution strategies.
                (02:14:24 PM) ALR: Maven is "nearest first", fail.
                (02:14:34 PM) ALR: "newest first" is nicer, though not always what you want.
                (02:14:39 PM) ALR: Static == declared
                (02:14:42 PM) lightguard_jp: You can create and use your own ivy resolver
                (02:14:55 PM) ALR: lightguard_jp: Can I apply the resolver per-dependency?
                (02:15:03 PM) ALR: Or is it applied per-project / build?
                (02:15:22 PM) ALR: For instance in EJB3 builds I might always want the latest versioned snapshot.
                (02:15:36 PM) sebersole: its applied per repo afaik
                (02:15:37 PM) ALR: But bring in latest real releases of like Tx, JPA, etc
                (02:15:37 PM) lightguard_jp: Per project, but you can explicitely declare deps and transitive deps
                (02:15:53 PM) ALR: wolfc: ^
                (02:16:05 PM) sebersole: lightguard_jp: but you can mix different types of repos in a project
                (02:16:30 PM) sebersole: wouldnt each get its own resolver?
                (02:16:52 PM) lightguard_jp: Um, I've never done that before, but it should work.
                (02:17:00 PM) lightguard_jp: ALR: Here's the overview: http://www.gradle.org/latest/docs/userguide/dependency_management.html
                (02:17:08 PM) ALR: lightguard_jp: Hehe, that's the one I've been reading.
                (02:17:22 PM) ALR: It shows promise but doesn't quite hit all nails.
                (02:17:50 PM) ALR: Basically I think it's a lot of what wolfc has done before using plain ol' Ant/Ivy
                (02:17:56 PM) sebersole: i mean worst of all cases you could write a buildscript or init-script that alters the deps
                (02:17:57 PM) lightguard_jp: What parts aren't there for you?
                (02:18:30 PM) ALR: Applying resolution strategies per-dependency
                (02:18:41 PM) ALR: Overriding the strategy as a build switch/property
                (02:21:09 PM) lightguard_jp: You may be able to something like that using the ResolverContainer and adding a resolver: http://www.gradle.org/latest/docs/javadoc/org/gradle/api/artifacts/ResolverContainer.html
                (02:24:56 PM) lightguard_jp: When you start talking resolvers though, you're in the realm of Ivy
                (02:25:11 PM) ALR: Yep, that's fine.
                (02:25:26 PM) ALR: I'm shocked this isn't a more standard requirement, to be honest.
                (02:25:27 PM) ***lightguard_jp wishes Hans or Adam were here
                (02:25:56 PM) ALR: Especially if you want to meet academic needs such as these http://martinfowler.com/articles/continuousIntegration.html
                (02:26:19 PM) ALR: Not that Fowler's got the only way, but it's well-documented and fits my cases.
                (02:26:44 PM) lightguard_jp: I know Hans said he did some work with snapshots a little while ago in gradle head, but I don't remember what.  I'd have to dig through my logs
                (02:26:55 PM) ALR: The idea of CI also gets hidden when you take sebersole's approach in hibernate
                (02:27:08 PM) ALR: Which is a more simplified tree on a shared release cycle
                (02:27:18 PM) ALR: It means less deps and less admin/management.




                • 5. Re: snapshot dependencies
                  Carlo de Wolf Master

                  To get our definitions straight we should not talk about continous integration, but bottom-up integration testing.

                  What we want to get away from is the Big Bang approach.



                  • 6. Re: snapshot dependencies
                    Thomas Diesler Master

                    We have made good experice using git submodules as described Using Git submodules for the AS7 build.


                    The AS7 build would contain any component that is not currently available in a stable released version. It is expected that submodules get added temporarily and removed again when a proper version is available (i.e. within a week). The submodule definition names the git repository including branch and sha1 of a specific commit.


                    We add submodules to a dedicated build folder called 'reactor'

                    • 7. Re: snapshot dependencies
                      Andrew Rubinger Master

                      I've been narrowing on this lately, with no conclusion right now other than that no tool currently exists which does real Continuous Integration involving dependencies.


                      Maven's notion of SNAPSHOTs are not reproducible and version ranges are broken and insufficient.  Dependency resolution strategies are per-build, not per-dependency, and they're not pluggable/configurable either.


                      The only documented pieces of "continuous integration" I've read cite the use of a single mainline into which sources are committed.  This negates the issue of dependencies entirely. 


                      Meaning that separate release cycles (more than one source tree) modularization and CI are conflicting concepts.


                      Until these are resolved, and we can bring in new dependency versions *without requiring a proper release* in a reproducible manner, I say CI in Java is a myth.


                      A recent chat with Agile author http://twitter.com/huettermann:


                      (04:57:39 PM) m2: ALR: you wanted to tell me, why Maven and snaps are that great
                      (04:57:49 PM) m2: ALR: you made me curious :-)
                      (04:57:52 PM) ALR: m2
                      (04:58:00 PM) m2: here I am
                      (04:58:04 PM) ALR: m2: Fantastic.
                      (04:58:08 PM) m2: :-)
                      (04:58:09 PM) ALR: I'm sharpening my case
                      (04:58:17 PM) ALR: For a blog this week, with some proposed solutins.
                      (04:58:20 PM) ALR: *solutions
                      (04:58:29 PM) ALR: Working off an academic base, Fowler's:
                      (04:58:42 PM) ALR: http://martinfowler.com/articles/continuousIntegration.html
                      (04:59:10 PM) ALR: This paper promotes the use of a single-tree "mainline".
                      (04:59:15 PM) ALR: Which houses all code.
                      (04:59:29 PM) ALR: "integration" in this sense regards to new source going into the tree.
                      (04:59:37 PM) ALR: What's absent here is the notion of dependencies.
                      (04:59:59 PM) ALR: As we gravitate towards a more highly-componentized modular layout, we make projects with very small scope.
                      (05:00:14 PM) ALR: These may then be assembled back into a larger runtime.
                      (05:00:45 PM) ALR: The benefit to this componentization is that we may keep release cycles disparate.
                      (05:00:56 PM) m2: sounds reasonable
                      (05:00:59 PM) ALR: Cool.
                      (05:01:06 PM) ALR: So then the issue becomes one of integration.
                      (05:01:19 PM) ALR: In Maven, this is done via standard dependency declarations.
                      (05:01:27 PM) ALR: To bring in "new" stuff, you use SNAPSHOTs.
                      (05:01:38 PM) maeste left the room (quit: Ping timeout: 252 seconds).
                      (05:01:51 PM) ALR: 1.0.0-SNAPSHOT is not a reproducible artifact.
                      (05:01:54 PM) ALR: It's a moving target.
                      (05:02:05 PM) ALR: Meaning "always grab the latest thing that was deployed".
                      (05:02:29 PM) ALR: Meaning that my builds which depend upon SNAPSHOTs are no longer reproducible with the same result each time.
                      (05:02:35 PM) ALR: As it depends upon that moving target
                      (05:02:40 PM) michaelschuetz left the room (quit: Ping timeout: 240 seconds).
                      (05:02:42 PM) m2: you can "bring in new stuff" also without using snapshots
                      (05:02:51 PM) ALR: m2: Bringing me to my next point
                      (05:02:55 PM) ALR: Version ranges.
                      (05:03:02 PM) ALR: Entirely a broken concept in Maven.
                      (05:03:13 PM) m2: hehe, yes?
                      (05:03:17 PM) ALR: Not to mention that dependency resolution with Maven is not pluggable.
                      (05:03:22 PM) ALR: It's "closest first".
                      (05:03:28 PM) ALR: Perhaps I want "most recent release"
                      (05:03:35 PM) ALR: Or perhaps I want "most recent SNAPSHOT".
                      (05:03:51 PM) ALR: And maybe I want to configure resolution per-dependency, not per-build.
                      (05:04:11 PM) m2: may I comment ?
                      (05:04:17 PM) ALR: m2: Please
                      (05:05:45 PM) ldimaggi_ left the room (quit: Quit: Leaving).
                      (05:05:54 PM) m2: some different topics ... firstly, you can bring in new work/artifacts without using snapshots -- you may use Maven without using snapshots at all. Secondly, yes fowlers definition .. I gave another one in my book: for me e.g. also managing dependencies are part of the game for sure.
                      (05:06:04 PM) m2: version ranges:
                      (05:06:22 PM) ALR: m2: Yep, for JBossAS we have banned SNAPSHOTs form the build.
                      (05:07:00 PM) ALR: m2: Link to book?  I'm trying to plug all holes with my developing theory.
                      (05:07:03 PM) m2: I dont use them so often .. this is too complex with many implications, only of value in special cases ... but, you can reconfigure dependencies to take special ones
                      (05:07:17 PM) m2: banned? nice approach :-)
                      (05:07:29 PM) ALR: s/form/from
                      (05:07:35 PM) ALR: Yep.
                      (05:08:10 PM) michaelschuetz [~m.schuetz@www.spree.de] entered the room.
                      (05:08:12 PM) ALR: "Reconfigure dependencies to take special ones"?
                      (05:08:25 PM) ALR: m2: ^
                      (05:08:48 PM) m2: you can configure snapshots to be updated once a day e.g. .. you only need a frozen version with reproducible artifacts whenn you release IMO
                      (05:09:12 PM) m2: yes, I mean you can configure the dependencies on a pretty fine-grained level
                      (05:09:17 PM) m2: the link: http://www.huettermann.net/alm/
                      (05:09:20 PM) ALR: Hehe, that's just the local policy.
                      (05:09:35 PM) ALR: m2: In JBossAS we have tens of committers every day.
                      (05:09:45 PM) ALR: When we introduce regression we need to know exactly how.
                      (05:09:46 PM) m2: yes, sure, I believe taht
                      (05:10:05 PM) ALR: Simply setting the update policy does not make the build reproducible.
                      (05:10:06 PM) ALR: Meaning:
                      (05:10:19 PM) ALR: If I check out r1000 from the repo, I should *always* get the same result.
                      (05:10:57 PM) ALR: (And that's just tens of committers to JBossAS every day.  Open it up to SNAPSHOTs and now we also consider that every SNAP dependency is a commit, so that number blows to hundreds).
                      (05:11:42 PM) m2: yes, I understand what you mean
                      (05:11:45 PM) ALR: Cool.
                      (05:11:49 PM) m2:
                      (05:11:51 PM) ALR: So I'm thinking something new:
                      (05:12:01 PM) ALR: Let say I have a component:
                      (05:12:15 PM) ALR: org.alrubinger:alrubinger-api:1.0.0-SNAPSHOT
                      (05:12:28 PM) ALR: I can publish a small descriptor to the Maven repo.
                      (05:12:39 PM) m2: for me thats the difference between a "version" and a "release" ... if snapshots don't work for you, you are not forced to use them
                      (05:12:48 PM) ALR: Which simply contains the coordinates (groupId,artifactId,version) and a pointer to the source SCM location.
                      (05:13:20 PM) ALR: Now any project with a SNAPSHOT dependency will not pull in some prebuilt artifact of this dependency.
                      (05:13:33 PM) ALR: But instead recurse in and checkout/build the SNAPSHOT itself.
                      (05:13:46 PM) ALR: Noting in the build log the revision used to do that.
                      (05:14:04 PM) ALR: Now we we want to replay the build, we have a noted log of the revisions from which each SNAPSHOT was built.
                      (05:14:25 PM) ALR: And can accurately note from build to build where changes leaked in from transitive SNAPSHOTs.
                      (05:14:56 PM) ALR: m2: To your point: "if snapshots don't work for you, you are not forced to use them"
                      (05:15:12 PM) ALR: True.   In fact we can't; they get unmanageable and don't scale well.
                      (05:15:25 PM) ALR: But I now am left with no way to see what's coming in down the pipeline.
                      (05:15:34 PM) ALR: My dependency versions are stale the second I put them in place.
                      (05:16:05 PM) ALR: Also we should really be able to run tests for *every* dependency version in a range.
                      (05:16:09 PM) ALR: Not necessarily resolve to one.
                      (05:16:14 PM) m2: so how do you handle the versions of your artifacts ?
                      (05:16:18 PM) m2: when do you increment ?
                      (05:16:43 PM) ALR: m2: That's the problem.
                      (05:16:49 PM) ALR: Take JBoss EJB3.
                      (05:16:57 PM) ALR: We have a dep on projectX:1.0.0
                      (05:17:15 PM) m2: Im not that involved in your releasing policies
                      (05:17:19 PM) ALR: Now JBossAS, which consumes EJB3, bumps to use projectX:1.1.0 in the real runtime.
                      (05:17:31 PM) ALR: Trying to paint a generic picture
                      (05:17:45 PM) m2: listening curiously ....
                      (05:17:47 PM) ALR: So EJB3 is left stale, testing on an old vesion.
                      (05:18:01 PM) ALR: While the dependency that really makes the runtime is incremented.
                      (05:19:10 PM) ALR: This is really a much more complex problem than current tools allow for.
                      (05:20:14 PM) ALR: m2: Have I yet justified my position?
                      (05:20:33 PM) m2: ALR: oh yes
                      (05:21:11 PM) ALR: m2: So my question is why everyone's knee-jerk reaction is the same as yours.
                      (05:21:15 PM) ALR: "Maven can do that".
                      (05:21:17 PM) m2: are you responsible for that releasing, or are you using it, or ??
                      (05:21:26 PM) ALR: m2: Which releasing?
                      (05:21:50 PM) m2: jboss as, ejb3, ...
                      (05:22:02 PM) ALR: m2: I release some EJB3 components and various other projects, yes.
                      (05:22:08 PM) m2: ok
                      (05:22:26 PM) m2: yes, there is no golden hammer available .. a tool is just a tool
                      (05:22:52 PM) ALR: m2: Yep, which explains my note on "opinionated software" earler.
                      (05:22:54 PM) ALR: *earlier
                      (05:22:59 PM) ALR: The tools don't support the desired process.
                      (05:23:07 PM) ALR: Which I think is necessary to do real component development.
                      (05:23:15 PM) ALR: So long as your sources are under one tree, you're fine.
                      (05:23:22 PM) m2: you should choose the tool that fits best for the process, not the other way round
                      (05:23:27 PM) ALR: Start to integrate external dependencies, and you lose mobility
                      (05:23:44 PM) ALR: m2: Right, so what is that tool?  Currently we see none.
                      (05:23:59 PM) ALR: I'm exploring the idea of adding some magic in the form of a Gradle plugin.
                      (05:24:06 PM) m2: I dont know how your process looks like
                      (05:24:08 PM) ALR: As the stuff I want to address is too deeply baked into Maven core.
                      (05:24:40 PM) ALR: m2: The process we need is to have a quick way to test builds against a range of incoming dependencies
                      (05:24:41 PM) m2: you can also add an own maven plugin or an ant script to your Maven build system
                      (05:24:43 PM) m2: why gradle?
                      (05:24:52 PM) ALR: m2: Because Maven is not pluggable here.
                      (05:25:07 PM) ALR: For instance I can't plug into the dependency resolution mechanism.
                      (05:26:15 PM) m2: yes, the core is not that "pluggable"
                      (05:26:23 PM) ALR:
                      (05:26:48 PM) ALR: Keep in mind I proposed to our project lead that we take a more pragmatic approach.
                      (05:26:54 PM) ALR: And make our process fit the tools.
                      (05:27:00 PM) ALR: It's the simplest way to make things work.
                      (05:27:07 PM) ALR: But it doesn't achieve the desire.
                      (05:27:25 PM) ALR: m2: Anyway, it's food for thought.  I need to let things percolate a bit more and blog later this week.
                      (05:28:04 PM) ALR: Would be fantastic to collaborate with some guys in existing build systems to get a reproducible snapshot mechanism or reliable version range system.
                      (05:28:15 PM) ALR: For now all of our builds are a series of hacks which work well enough.
                      (05:28:22 PM) ALR: But eventually break down under scale.




                      • 8. Re: snapshot dependencies
                        Paul Gier Master

                        Just trying to summarize some of the main discussion points so far


                        Reproducible Snapshot Builds


                        This means we can reproduce a build (on Hudson for example) which uses un-released (snapshot) dependencies.  We're limited by the Maven repository structure which normally saves each snapshot build with a unique timestamp and build number.  The problem is that our builds don't record which snapshot dependencies were used.  Here are some options for this


                        versions-maven-plugin - This would require running the plugin on the command line once before and once after each deployment.  It's not practical for developers to do this every time, but maybe it could be automated if the snapshot deployments are done from Hudson


                        Maven Ant tasks or Gradle - Both of these have the ability to generate a POM during the build/deploy process.  I don't think either of them currently have support for generating the resolved snapshot versions, but it could be something for the future.


                        So let's say that we do get fully resolved snapshot dependency trees into the repsitory.  The next issue to deal with is when you see some Hudson failures, how do you run your local build with the same set of dependencies?  Since these locked snapshot versions are not stored in svn, the versions would have to be copied maybe from the Hudson workspace?


                        The other option would be to always check in locked snapshots to svn/git.  One problem with this is that the snapshots are periodically cleaned up from the repository and the specific timestamped versions may no longer exist in the repo.  Although it's worth noting that this is also a risk using standard snapshot dependencies since they can be released and removed from the repo, it just wouldn't occur nearly as often as timestamped snapshots.


                        Testing Multiple Dependency Sets


                        This is not supported in Maven, but is possible with Gradle or with the Maven Ant tasks.  Either of those would allow you to define multiple dependency sets and then run the testsuite against those dependencies.  Running against a range of dependencies would be more difficult than manually defined sets of dependencies.  Although I'm not sure how practical it is to use arbitrary ranges because the number of possibilities would grow very quickly.

                        • 9. Re: snapshot dependencies
                          Paul Gier Master

                          Carlo de Wolf wrote:


                          To get our definitions straight we should not talk about continous integration, but bottom-up integration testing.

                          What we want to get away from is the Big Bang approach.




                          Maybe the solution to our snapshots problem is really to just have more stable APIs and better testing at the lower level components (bottom-up testing).  If we minimize stuff breaking from one snapshot to the next, then there isn't such a problem with not being able to locate and use the old one.  Then we could use normal Maven snapshots in the higher level components without as much concern.