You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@maven.apache.org by David McCabe <da...@sunlightd.com> on 2011/05/07 18:10:02 UTC

Best practice for migrating existing system

We've been using a custom-made component-based build system for many years,
built using a number of Ant scripts, and we'd really like to move to
something more standard. We'd like to go with Maven, Subversion and Nexus,
but our build processes are a little different from the usual and it would
be nice to know what is the 'right' way to address some of the versioning
issues.

Our applications are made up of a few dozen components, some of which are
shared between projects and some of which are project-specific. Each of
these components currently has a 4-component build number
"major.minor.patch.build". When building a component, its build number is
incremented. A new major, minor or patch version resets the build version to
zero. I'm happy to change a dot to a hyphen, and I'd also be perfectly happy
for that build number to be a Subversion revision number, but I'm not happy
to go for a SNAPSHOT-style date/time: try telling someone your latest
version is "3.6.0.20110507170144".

The 'released' version of a component is the last build number that
component is built with. Once a component has been 'released' it cannot be
built as a new version; the rest of the version number needs to be
incremented. This is somewhat like Maven's release process except that we do
not want to renumber or rebuild the components for release; integration and
system tests will reveal when a project (and its constituent components) are
ready for release, and we're not going to re-run the entire test suite on a
functionally identical build. It would be nice to protect a 'released'
component from being rebuilt but that's hardly mandatory.

Obviously, when a component is built and its build number incremented, all
dependencies need to have their version numbers updated and be rebuilt. It
would be nice if the dependencies could automatically pick up the 'latest'
version of a major.minor.patch dependency version; I understand this can be
done using Maven version ranges.

When doing a 'real' build I would like the components to be 'tagged' in
Subversion with the built version numbers and for that tag to reference the
actual set of build dependencies (rather than a version range). Ideally, I'd
have a Subversion style:

Component-name
|- trunk
|- branches
|- |- 1.0.0
|- |- 1.0.1
|- |- 1.1.0
|- tags
|- |- 1.0.0-0
|- |- 1.0.0-1
|- |- 1.0.1-0

I would also like to be able to do 'test' builds without tagging; maybe the
tagging should be separate so I can try to build the whole lot to my local
repository, and if the build is successful and all automated tests pass
along the way only then update Nexus and tag in Subversion.

What I want, therefore, is a system in which, for a set of top-level
components to be built, it would then evaluate the set of transitive
dependencies of those components as specified in Subversion (not Nexus or
the local repository), work out the complete list of out-of-date components
to build and then build all of those components such that the top-level
components represent the current state of Subversion. Plainly, if the build
is up-to-date with Subversion, nothing should be built.

I accept that this is a job for Python, but I am wondering how much of this
process can be done with Maven without cluttering the per-project POMs, even
if minor modifications need to be made.

Thanks in advance,
David McCabe


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Ron Wheeler <rw...@artifact-software.com>.
On 07/05/2011 6:59 PM, David McCabe wrote:
> Thanks for the information. I think I may need to clarify some things.
>
>>> Our applications are made up of a few dozen components, some of which
>>> are shared between projects and some of which are project-specific.
>>> Each of these components currently has a 4-component build number
>>> "major.minor.patch.build". When building a component, its build number
>>> is incremented. A new major, minor or patch version resets the build
>>> version to zero. I'm happy to change a dot to a hyphen, and I'd also
>>> be perfectly happy for that build number to be a Subversion revision
>>> number, but I'm not happy to go for a SNAPSHOT-style date/time: try
>>> telling someone your latest version is "3.6.0.20110507170144".
>> A SNAPSHOT is not a release and ideally should never be spoken off outside
>> the immediate team and even then you need to explain what a SNAPSHOT
>> does and does not yet do and what are the restrictions on its use and
> where
>> it does not respect the specifications. Or you can just let the other team
>> members curse you out when they spend hours trying to find out why their
>> software does not work when they use your SNAPSHOTs.
>>
>> SNAPSHOTS are very useful but version 1.3.5.6 is not the same as 1.3.5.6-
>> SNAPSHOT.
>> One comes with a warranty and the other comes with a warning.
> Absolutely, but therein lies the problem. If we were to use SNAPSHOT, it
> would be 1.3.5-SNAPSHOT. In Maven terminology, this would result in you
> eventually 'releasing' a 1.3.5-SNAPSHOT as version 1.3.5.
>
> Our problem is that the builds that get tested are, presumably, SNAPSHOT
> builds of each of the components modified since the last project release.
> The 'Maven way' of doing this appears to be for every candidate for project
> release, I 'release' every component.
You deploy a SNAPSHOT until you are ready to release 1.3.5 or release 
1.3.5-RC1 or you want to create a release candidate. We don't use this 
but I think that a lot of people do this.
> If the testing fails (or a product
> manager changes his mind about how a feature should work, e.g. from beta
> feedback) then we would wind up 'releasing' each component modified in
> making that change before we had a build that could again be a 'release
> candidate'. Is that correct? This seems to make Maven 'release' more of a
> 'make-release-candidate' - and really quite time-consuming.
>
I think that you are right here.
We have made sure that our modules are functional and are working 
towards better SOA with every release so we do not have a lot of 
functions that cross modules.
Changes tend to be local once we get close to releases.
Using Betas and RCs will help if you are prone to late cycle changes in 
functionality.

It is not that hard to change the version ID in each POM. Takes a few 
seconds for each POM. You can automate this with the maven release  
plug-in if you think that this is too much work to do this manually. We 
don't do this but you can get others in the forum to guide you in this.

> This isn't a Web application - this is a 60-component medical imaging
> workstation, and the component dependency graph is deep rather than broad. A
> change can be only a line of code but still result in a rebuild of many
> components.
>
Doesn't change things very much.
Not sure why a single line of code should result in rebuilding more than 
1 module.
You will have to rebuild the assembly of the application so I see only 2 
modules being rebuilt in your example.
> Maybe the idea is that one can 'release' all of the components after
> testing? My major concern is trying to convince our quality team that having
> built the application against one set of versions that another set of
> versions are fundamentally identical.
You test the release after you build it. One hopes that the release is 
the same as the last release candidate and only requires some very 
limited functional user testing after the automated tests are run.
> Is there some way for me to check that
> a component's build-time transitive dependencies' versions were all
> 'released'?
>
Only use releases versions of dependencies in your build. You will get 
what you specify. If the POM that builds your run-time application calls 
for 1.3.5 of dependency A, then you are sure that your application is 
using version 1.3.5 of jar A.
>>> What I want, therefore, is a system in which, for a set of top-level
>>> components to be built, it would then evaluate the set of transitive
>>> dependencies of those components as specified in Subversion (not Nexus
I don't think so. You tag and branch the Subversion versions based on 
the things that you build.
>> or
>>> the local repository), work out the complete list of out-of-date
>> components
>>> to build and then build all of those components such that the top-level
>>> components represent the current state of Subversion. Plainly, if the
> build
>>> is up-to-date with Subversion, nothing should be built.
>>>
>> Too much work. Just run a clean development workflow and do things the
>> Maven way and your life will be much more pleasant and your development
>> team much happier with each other.
>> Guys who release crap will soon find out that their friends will jump on
>> them and the boss will know that a crappy piece of software was released
>> when it was still at the SNAPSHOT stage.
> Alas, this is a large project but not a large team, and many components do
> not have single ownership because there just aren't enough people to do
> that. There are five of us across three projects and the component
> versioning process is a means to allow us to manage this size of project. I
> have to be absolutely sure that each check-in that any of us made has made
> it to the installer. I currently do this manually, and it's very
> time-consuming and error-prone (particularly since we're on CVS, so I can't
> just look at the revision log since the last build...). If a change has
> occurred a long way down the dependency tree, it needs a way to propagate
> upwards.
>
We are a team of 2 but used to be 3 with over 80 modules making up 2 
distinct applications with no code overlap.
Ownership is not an issue if you use Subversion, Nexus and Maven 
properly and have a good modular design.
The POM file with its description of the modules dependencies is the 
gospel over Subversion.

If the POM says that you built version 1.3.5.1 of your module A with 
version 1.3.5.0 of dependency B, that is what you did.
You don't care what Subversion says about your modules A or B.

In your current system, you spend a lot of effort controlling code 
versions because your build system does not care about versions so you 
are forced to look at Subversion or CVS to control versions.
Once your build system (Maven) starts to care about versions and 
guarantees that builds use the right versions of all your dependencies, 
your life gets a lot easier.
You can commit anything to Subversion that you want to share, regardless 
of the state of the code because anyone who checks out a module can see 
from the POM which version the code is supposed to be building.
If you build a release or SNAPSHOT using  your Nexus dependencies (My 
advice is to never build with a workspace artifact.)  you will know 
exactly what you are getting regardless of what state the Subversion 
code is in.

Even if you forget to tag the Subversion version, you can find the right 
version of the code by looking at the Subversion history to see when the 
POM changed.
It is easier if you handle Subversion right but not fatal if you don't.
Getting people to put useful comments on every commit to Subversion is 
really helpful.

SNAPSHOTS are a powerful tool to help a team work together.
Stubs, partial implementations can be shared as SNAPSHOTS.
The person providing the SNAPSHOT and the person using it need to 
communicate so that as the SNAPSHOT dependency gets more functionality 
and fewer bugs, the person writing the code that depends on it is aware 
of the state.

> I am trying to find out what the 'Maven way' is for each of these issues,
> but there has to be flexibility. Maven is the closest thing out there to the
> system we have right now, and I would much prefer to use it than to bolt on
> additional functionality to our large Ant script collection... but if it
> won't fit our organization, then it is Maven that will go.
>
Ant and Maven are based on completely different philosophies.

I don't see anything yet that you are doing or building that could not 
be handled by Maven.
Thousands of teams are building applications like yours.

Try to adopt the simplest Maven approach and then add complexity later 
if you see a clear way to optimize your workflow.
Trying to optimize your use of Maven at the start can get you into a 
complex and poorly structured set of Maven modules with too many obscure 
plug-ins.
My impression is that you need to use the compile plug-in and the 
assembly plug-in to build the Desktop jar.

My advice is to start out by taking the time to manually manage the 
updating of the POM versions until you get comfortable with the workflow 
and then see how this can be automated or simplified.
We opted for simplification over automation and put in the time up front 
in a new release to plan how the versions of all of the modules that 
make up the application will be affected by the proposed changes.
We have decided to treat our own modules in the same way we treat third 
party modules.
We do not force all of the modules to have the same version number.
If module B is not affected by the change, version 1.3.5.1  of module A 
can depend on version 1.3.5.0 of module B. We start with module A 
version 1.3.5.1-SNAPSHOT depending in release 1.3.5.0 of module B.
This reduced the effort required to manage the project when adding new 
features or fixing bugs which have limited scope.

I hope that this helps you give you the confidence to move forward.

Ron
> Thanks,
> David
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


RE: Best practice for migrating existing system

Posted by David McCabe <da...@sunlightd.com>.
Thanks for the information. I think I may need to clarify some things.

> > Our applications are made up of a few dozen components, some of which
> > are shared between projects and some of which are project-specific.
> > Each of these components currently has a 4-component build number
> > "major.minor.patch.build". When building a component, its build number
> > is incremented. A new major, minor or patch version resets the build
> > version to zero. I'm happy to change a dot to a hyphen, and I'd also
> > be perfectly happy for that build number to be a Subversion revision
> > number, but I'm not happy to go for a SNAPSHOT-style date/time: try
> > telling someone your latest version is "3.6.0.20110507170144".
> A SNAPSHOT is not a release and ideally should never be spoken off outside
> the immediate team and even then you need to explain what a SNAPSHOT
> does and does not yet do and what are the restrictions on its use and
where
> it does not respect the specifications. Or you can just let the other team
> members curse you out when they spend hours trying to find out why their
> software does not work when they use your SNAPSHOTs.
> 
> SNAPSHOTS are very useful but version 1.3.5.6 is not the same as 1.3.5.6-
> SNAPSHOT.
> One comes with a warranty and the other comes with a warning.

Absolutely, but therein lies the problem. If we were to use SNAPSHOT, it
would be 1.3.5-SNAPSHOT. In Maven terminology, this would result in you
eventually 'releasing' a 1.3.5-SNAPSHOT as version 1.3.5.

Our problem is that the builds that get tested are, presumably, SNAPSHOT
builds of each of the components modified since the last project release.
The 'Maven way' of doing this appears to be for every candidate for project
release, I 'release' every component. If the testing fails (or a product
manager changes his mind about how a feature should work, e.g. from beta
feedback) then we would wind up 'releasing' each component modified in
making that change before we had a build that could again be a 'release
candidate'. Is that correct? This seems to make Maven 'release' more of a
'make-release-candidate' - and really quite time-consuming.

This isn't a Web application - this is a 60-component medical imaging
workstation, and the component dependency graph is deep rather than broad. A
change can be only a line of code but still result in a rebuild of many
components.

Maybe the idea is that one can 'release' all of the components after
testing? My major concern is trying to convince our quality team that having
built the application against one set of versions that another set of
versions are fundamentally identical. Is there some way for me to check that
a component's build-time transitive dependencies' versions were all
'released'?

> > What I want, therefore, is a system in which, for a set of top-level
> > components to be built, it would then evaluate the set of transitive
> > dependencies of those components as specified in Subversion (not Nexus
> or
> > the local repository), work out the complete list of out-of-date
> components
> > to build and then build all of those components such that the top-level
> > components represent the current state of Subversion. Plainly, if the
build
> > is up-to-date with Subversion, nothing should be built.
> >
> Too much work. Just run a clean development workflow and do things the
> Maven way and your life will be much more pleasant and your development
> team much happier with each other.
> Guys who release crap will soon find out that their friends will jump on
> them and the boss will know that a crappy piece of software was released
> when it was still at the SNAPSHOT stage.

Alas, this is a large project but not a large team, and many components do
not have single ownership because there just aren't enough people to do
that. There are five of us across three projects and the component
versioning process is a means to allow us to manage this size of project. I
have to be absolutely sure that each check-in that any of us made has made
it to the installer. I currently do this manually, and it's very
time-consuming and error-prone (particularly since we're on CVS, so I can't
just look at the revision log since the last build...). If a change has
occurred a long way down the dependency tree, it needs a way to propagate
upwards.

I am trying to find out what the 'Maven way' is for each of these issues,
but there has to be flexibility. Maven is the closest thing out there to the
system we have right now, and I would much prefer to use it than to bolt on
additional functionality to our large Ant script collection... but if it
won't fit our organization, then it is Maven that will go.

Thanks,
David


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Wayne Fay <wa...@gmail.com>.
> of 'common' component that (a) gets a lot of changes and (b) has many
> things that depend on it -- at least in the early phases of building
> out a large system. Over time, that component slows down, or even
> splits up.

Yes, this echoes my experience as well.

Wayne

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Benson Margulies <bi...@gmail.com>.
Not every problem is solved by waving the lemon of 'SOA' over it and
expecting it to turn into lemonade. Some of us code things that have
actual computations in them, and those computations have shared,
reused classes, and those classes do not belong behind a web service
-- either for performance or sheer common sense.

And the effect of this, in toto, is that it highlights some of the
edges of what the maven-release-plugin is useful for. When working on
the far side of those edges, it makes (to me) more sense to find
another procedure than to warp the software architecture.

There's a line between "the maven way" and "procrustes' bed," and that
line does not necessarily pass through a point at infinity.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Ron Wheeler <rw...@artifact-software.com>.
On 09/05/2011 11:25 AM, Benson Margulies wrote:
> It sounds good, but there's a medium size in which it doesn't quite
> work out this way. You can't create a new maven module for every
> single class. Thus, in my experience, we have ended up with some sort
> of 'common' component that (a) gets a lot of changes and (b) has many
> things that depend on it -- at least in the early phases of building
> out a large system. Over time, that component slows down, or even
> splits up.
Every class is way too much.

Separating business functions from utilities is a good place to start.

Moving to SOA and breaking the business processes into services is a 
"good thing".
This hides datastructure details from many levels and isolates 
processing into services that are shared.
Functional changes start to have smaller scope and it becomes easier to 
identify the modules that are affected.

Ron
> On Mon, May 9, 2011 at 11:10 AM, Ron Wheeler
> <rw...@artifact-software.com>  wrote:
>> On 09/05/2011 10:42 AM, Wayne Fay wrote:
>>>> As far as I can tell, Option 1 is only practical once the velocity of
>>>> change slows down to the point where at least some components sit
>>>> unchanged for a good long time -- that is, for more than one
>>>> development iteration. It's only useful to 'use a version with a
>>> But it seems like a good (best?) practice to break modules up into
>>> functional components such that parts which have no reason to change
>>> for a given release are not changed. If you find it annoying that a
>>> small change in a small piece of code that is wrapped up inside a much
>>> larger library means the entire library has to bump a version, you may
>>> want to consider breaking the smaller bits out into its own
>>> independent module. Especially if the velocity of change in those
>>> small bits is significantly greater than the velocity of the rest of
>>> the bits.
>>>
>>> This does mean that you may end up with 150 modules rather than 70.
>>> Suddenly your processes which were OK at 70 modules are really not
>>> working with 150, so you may need to be willing to adjust your
>>> processes etc as well.
>> +1
>> More robust structure
>> Easier to assure that small functional modules are working correctly
>> Easier to test libraries than applications - usually.
>> Increases likeliness of sharing of code.
>>
>> Lots of other good reasons to do this.
>>
>> Maven and Nexus makes it easy to manage this.
>>
>> Ron
>>> Wayne
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
>>> For additional commands, e-mail: users-help@maven.apache.org
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
>> For additional commands, e-mail: users-help@maven.apache.org
>>
>>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Benson Margulies <bi...@gmail.com>.
It sounds good, but there's a medium size in which it doesn't quite
work out this way. You can't create a new maven module for every
single class. Thus, in my experience, we have ended up with some sort
of 'common' component that (a) gets a lot of changes and (b) has many
things that depend on it -- at least in the early phases of building
out a large system. Over time, that component slows down, or even
splits up.

On Mon, May 9, 2011 at 11:10 AM, Ron Wheeler
<rw...@artifact-software.com> wrote:
> On 09/05/2011 10:42 AM, Wayne Fay wrote:
>>>
>>> As far as I can tell, Option 1 is only practical once the velocity of
>>> change slows down to the point where at least some components sit
>>> unchanged for a good long time -- that is, for more than one
>>> development iteration. It's only useful to 'use a version with a
>>
>> But it seems like a good (best?) practice to break modules up into
>> functional components such that parts which have no reason to change
>> for a given release are not changed. If you find it annoying that a
>> small change in a small piece of code that is wrapped up inside a much
>> larger library means the entire library has to bump a version, you may
>> want to consider breaking the smaller bits out into its own
>> independent module. Especially if the velocity of change in those
>> small bits is significantly greater than the velocity of the rest of
>> the bits.
>>
>> This does mean that you may end up with 150 modules rather than 70.
>> Suddenly your processes which were OK at 70 modules are really not
>> working with 150, so you may need to be willing to adjust your
>> processes etc as well.
>
> +1
> More robust structure
> Easier to assure that small functional modules are working correctly
> Easier to test libraries than applications - usually.
> Increases likeliness of sharing of code.
>
> Lots of other good reasons to do this.
>
> Maven and Nexus makes it easy to manage this.
>
> Ron
>>
>> Wayne
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
>> For additional commands, e-mail: users-help@maven.apache.org
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Ron Wheeler <rw...@artifact-software.com>.
On 09/05/2011 10:42 AM, Wayne Fay wrote:
>> As far as I can tell, Option 1 is only practical once the velocity of
>> change slows down to the point where at least some components sit
>> unchanged for a good long time -- that is, for more than one
>> development iteration. It's only useful to 'use a version with a
> But it seems like a good (best?) practice to break modules up into
> functional components such that parts which have no reason to change
> for a given release are not changed. If you find it annoying that a
> small change in a small piece of code that is wrapped up inside a much
> larger library means the entire library has to bump a version, you may
> want to consider breaking the smaller bits out into its own
> independent module. Especially if the velocity of change in those
> small bits is significantly greater than the velocity of the rest of
> the bits.
>
> This does mean that you may end up with 150 modules rather than 70.
> Suddenly your processes which were OK at 70 modules are really not
> working with 150, so you may need to be willing to adjust your
> processes etc as well.
+1
More robust structure
Easier to assure that small functional modules are working correctly
Easier to test libraries than applications - usually.
Increases likeliness of sharing of code.

Lots of other good reasons to do this.

Maven and Nexus makes it easy to manage this.

Ron
> Wayne
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Wayne Fay <wa...@gmail.com>.
> As far as I can tell, Option 1 is only practical once the velocity of
> change slows down to the point where at least some components sit
> unchanged for a good long time -- that is, for more than one
> development iteration. It's only useful to 'use a version with a

But it seems like a good (best?) practice to break modules up into
functional components such that parts which have no reason to change
for a given release are not changed. If you find it annoying that a
small change in a small piece of code that is wrapped up inside a much
larger library means the entire library has to bump a version, you may
want to consider breaking the smaller bits out into its own
independent module. Especially if the velocity of change in those
small bits is significantly greater than the velocity of the rest of
the bits.

This does mean that you may end up with 150 modules rather than 70.
Suddenly your processes which were OK at 70 modules are really not
working with 150, so you may need to be willing to adjust your
processes etc as well.

Wayne

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Benson Margulies <bi...@gmail.com>.
Having tried more or less Ron's prescription, I have to offer a
caveat. You spend a lot of time watching the release plugin running.

Frequently, a group of inter-related components has some component
that accumulates shared utilities. In my experience, at least, the
shared component is very busy -- all the users of it find reasons to
change it or add things to it. Call it 'com.mon:common' (groupid
com.mon, artifactid common).

So, you start out on day 1 with all versions at 1-SNAPSHOT. To try to
take Ron's prescription seriously, the first thing you do is run the
release plugin on everything. OK, now there's a '1' of each component
in your copy of nexus. And now you have to make a decision.

Option 1: All the other projects reference com.mon:common:1. Everyone
is using the version with the warranty: for the five minutes that
elapse before everyone feels the need to make a modification to
com.mon:common. Now, each of those people grimaces, and modifies the
pom of the thing they are working on to say, '2-SNAPSHOT' for the
dependency on com.mon:common. When it all works, they check in their
new version of the source of com.mon:common. Now they have to release
it, and then update everything to use the new version. And probably
collide with other people who just did the same thing.

Option 2: All the other projects reference com.mon:common:2-SNAPSHOT.
To maximize sanity, assume that *no-one ever deploys a snapshot*.
Everyone downloads all the source and builds everything, so that they
have a local snapshot. They make whatever changes they need to, and
check in as needed. Once per iteration (scrum-speaking), someone does
an organized job of releasing everything.

As far as I can tell, Option 1 is only practical once the velocity of
change slows down to the point where at least some components sit
unchanged for a good long time -- that is, for more than one
development iteration. It's only useful to 'use a version with a
warranty' if that you can use that version, unchanged, for your
iteration. If you have to make changes, or use the latest changes in
svn, every day, you might as well just be building it yourself and use
your local SNAPSHOT.

Note that 'automatically releasing and bumping version numbers every
night' is here nowhere. It leads to constant churn in the pom files,
source control merge conflicts, and other distress.

Releasing something, *in my opinion* (and all of this is a matter of
*opinion*) only makes sense when that release will have a half-life of
at least a week.

Every 'release' results in changes to all the poms, plus tagging and
bagging in svn.

If you want to test packages every night, my suggestion is to test a
snapshot, and use the build number plugin to assign a number that is
both unique and suitable concise. Further, *do not* publish those
snapshots to a repo where developers will download them. That leads to
the dreaded 'SNAPSHOT skew screw' and you don't want that. Have the
build number plugin capture the svn rev # for the checkout of the
tree. That's all you need to be able to repro any test failures, you
don't need an svn tag.

If the pitfalls and evils of deploying SNAPSHOTs aren't clear to any
interested reader, I'd be happy to type up the standard explanation.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org


Re: Best practice for migrating existing system

Posted by Ron Wheeler <rw...@artifact-software.com>.
On 07/05/2011 12:10 PM, David McCabe wrote:
> We've been using a custom-made component-based build system for many years,
> built using a number of Ant scripts, and we'd really like to move to
> something more standard. We'd like to go with Maven, Subversion and Nexus,
> but our build processes are a little different from the usual and it would
> be nice to know what is the 'right' way to address some of the versioning
> issues.
>
> Our applications are made up of a few dozen components, some of which are
> shared between projects and some of which are project-specific. Each of
> these components currently has a 4-component build number
> "major.minor.patch.build". When building a component, its build number is
> incremented. A new major, minor or patch version resets the build version to
> zero. I'm happy to change a dot to a hyphen, and I'd also be perfectly happy
> for that build number to be a Subversion revision number, but I'm not happy
> to go for a SNAPSHOT-style date/time: try telling someone your latest
> version is "3.6.0.20110507170144".
A SNAPSHOT is not a release and ideally should never be spoken off 
outside the immediate team and even then you need to explain what a 
SNAPSHOT does and does not yet do and what are the restrictions on its 
use and where it does not respect the specifications. Or you can just 
let the other team members curse you out when they spend hours trying to 
find out why their software does not work when they use your SNAPSHOTs.

SNAPSHOTS are very useful but version 1.3.5.6 is not the same as 
1.3.5.6-SNAPSHOT.
One comes with a warranty and the other comes with a warning.


> The 'released' version of a component is the last build number that
> component is built with. Once a component has been 'released' it cannot be
> built as a new version; the rest of the version number needs to be
> incremented. This is somewhat like Maven's release process except that we do
> not want to renumber or rebuild the components for release; integration and
> system tests will reveal when a project (and its constituent components) are
> ready for release, and we're not going to re-run the entire test suite on a
> functionally identical build. It would be nice to protect a 'released'
> component from being rebuilt but that's hardly mandatory.
>
Nexus will prevent you from redeploying the same release so you have 
some protection. In Maven, releases are immutable.
If you follow best practices with your POM and stay away from such evils 
as "Version Ranges", your builds are repeatable.
Never build a release with SNAPSHOT - there lies the road to damnation!

> Obviously, when a component is built and its build number incremented, all
> dependencies need to have their version numbers updated and be rebuilt. It
> would be nice if the dependencies could automatically pick up the 'latest'
> version of a major.minor.patch dependency version; I understand this can be
> done using Maven version ranges.
>
Bad idea.
Leads to unrepeatable builds.
Make people release dependencies with a warranty.
It is better to use SNAPSHOTs until you are ready to release the top 
level modules and insist that the lower level dependencies be released 
first.
Everyone keeps their versions at SNAPSHOTs until they warrant it is 
release quality.
> When doing a 'real' build I would like the components to be 'tagged' in
> Subversion with the built version numbers and for that tag to reference the
> actual set of build dependencies (rather than a version range). Ideally, I'd
> have a Subversion style:
>
> Component-name
> |- trunk
> |- branches
> |- |- 1.0.0
> |- |- 1.0.1
> |- |- 1.1.0
> |- tags
> |- |- 1.0.0-0
> |- |- 1.0.0-1
> |- |- 1.0.1-0
>
Yes. You are right. You can tag SNAPSHOTS but people seldom do.

> I would also like to be able to do 'test' builds without tagging; maybe the
> tagging should be separate so I can try to build the whole lot to my local
> repository, and if the build is successful and all automated tests pass
> along the way only then update Nexus and tag in Subversion.
Nexus will handle SNAPSHOTS and you can deploy them as long as your 
friends are made aware of where you are in terms of functionality and 
robustness.
> What I want, therefore, is a system in which, for a set of top-level
> components to be built, it would then evaluate the set of transitive
> dependencies of those components as specified in Subversion (not Nexus or
> the local repository), work out the complete list of out-of-date components
> to build and then build all of those components such that the top-level
> components represent the current state of Subversion. Plainly, if the build
> is up-to-date with Subversion, nothing should be built.
>
Too much work. Just run a clean development workflow and do things the 
Maven way and your life will be much more pleasant and your development 
team much happier with each other.
Guys who release crap will soon find out that their friends will jump on 
them and the boss will know that a crappy piece of software was released 
when it was still at the SNAPSHOT stage.

> I accept that this is a job for Python, but I am wondering how much of this
> process can be done with Maven without cluttering the per-project POMs, even
> if minor modifications need to be made.
>
Try not to reinvent a process that works for thousands of other projects.

> Thanks in advance,
> David McCabe
>

Our LMS Portal application has over 70 Maven projects and uses well over 
50 third party libraries. It has been in production and development for 
more than 3 years.
It includes Tomcat servlets, Web Services and standalone batch jobs.
We use a very clean out-of-the-box Maven workflow with no odd plug-ins 
or version ranges.
Maven and Nexus are a great combination. We also use Subversion.

Good luck and you will find this forum a great place for advice. Not 
everyone is as opinionated as me and some of them are really great Maven 
experts and are willing to help others a lot.
You did a very good thing by starting off with a description of what you 
are trying to accomplish. A lot of people show up with detailed 
questions with no context and get "right" answers that lead them down a 
bad path that takes weeks to straighten out.

I hope that this helps.

Ron
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
> For additional commands, e-mail: users-help@maven.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@maven.apache.org
For additional commands, e-mail: users-help@maven.apache.org