Skip to content

Wakaleo Consulting

  Home Blog Maven Mythbusters - Maven automatically updates for every build
Maven Mythbusters - Maven automatically updates for every build PDF Print E-mail
Wednesday, 06 January 2010 20:53

Maven seems to be one of those topics that brings out passion in many developers. Apparently, some developers love it, and find it a highly valuable and time-saving tool, whereas others hate it with a passion. (Of course there are still others who just want to get on with the job, but those ones usually keep quiet on the blogosphere). Every once in a while someone comes out with a blog entry explaining in more or less detail what they dislike so much about Maven. Sometimes these articles contain constructive criticism that allows Maven to evolve in the right direction. That's great. Sometimes they contain inaccuracies or misunderstandings about how Maven works. Sometimes they are just downright wrong. But they nevertheless represent a perception of Maven in parts of the Java community. So in this series of articles, I want to take a look at some of the common myths and ideas that circulate about Maven, and see how they stand up to the light of scientific examination.

Myth Number 1: Maven automatically checks for, and downloads, updates at every build

The first myth we will tackle involves Maven's network habits. Indeed, there seems to be a widely spread idea about Maven that it slows down your build with excessive network access. Here is quote from a recent blog entry illustrating and propagating this idea:

"Maven is broken and wrong if it thinks nothing of slowing down every build by connecting to the network and checking every dependency for any updates, and automatically downloading them"

Interesting. Indeed, it would be a grievous fault! Let's see how this idea stands up to the facts.

Actually, this idea is flat out wrong. In fact, Maven only checks for SNAPSHOT updates once a day by default, and even this is configurable. Maven 3 takes things even further: automatic updates will be turned off by default - you will have to explicitly ask for updates (using the -U option).

Maven doesn't need to check for core plugin updates at all - since Maven 2.0.9, the versions of the core plugins are bound to the version of Maven you are using, unless you explicitly tell it otherwise. So no updates here either.

However, like snapshots, Maven will check for plugin updates once a day if you don't provide a version of your plugin. So provide versions for your plugins, or accept the overhead of some network network access once every 24 hours. But it is recommended practice (and common sense, really) to specify the version number of any plugins you use in your build. If you do have explicit plugin version numbers for non-lifecycle plugins, it won't need to check for plugin updates either.

So in theory, this myth should be well and truly busted. However, true to MythBuster tradition, we'll check this hypothesis with a few tests. First, let's try with a simple multi-module project. To make things interesting, I've deleted a few directories from my local repository to force Maven to download some stuff initially:

$ mvn clean verify
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   Tweeter
[INFO]   Tweeter domain model
[INFO]   Tweeter service layer
[INFO]   Tweeter web application
[INFO] ------------------------------------------------------------------------
[INFO] Building Tweeter
[INFO]    task-segment: [clean, verify]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
Downloading: http://localhost:8081/nexus/content/groups/public/org/easyb/easyb/
0.9.6/easyb-0.9.6.pom
2K downloaded  (easyb-0.9.6.pom)
Downloading: http://localhost:8081/nexus/content/groups/public/org/easyb/easyb/
0.9.6/easyb-0.9.6.jar
343K downloaded  (easyb-0.9.6.jar)
[INFO] [easyb:test {execution: default}]
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Tweeter ............................................... SUCCESS [4.434s]
[INFO] Tweeter domain model .................................. SUCCESS [9.724s]
[INFO] Tweeter service layer ................................. SUCCESS [1.722s]
[INFO] Tweeter web application ............................... SUCCESS [30.865s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 47 seconds
[INFO] Finished at: Tue Jan 05 12:14:12 NZDT 2010
[INFO] Final Memory: 63M/123M
[INFO] ------------------------------------------------------------------------
2010-01-05 12:14:13.588::INFO:  Shutdown hook executing
2010-01-05 12:14:13.090:/tweeter-web:INFO:  Closing Spring root WebApplicationContext
2010-01-05 12:14:13.092::INFO:  Shutdown hook complete

That downloaded the easyb plugin because it didn't have it locally. Fair enough, that's what its supposed to do. To boot, it downloads dependencies in parallel when it can, so it's pretty fast. What Maven does downloads, it needs to build your application, and it does it only once. Not once per project, but once, period. But back to the subject in question: now let's rerun to see if it tries to download any updates.

$	mvn clean verify
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   Tweeter
[INFO]   Tweeter domain model
[INFO]   Tweeter service layer
[INFO]   Tweeter web application
[INFO] ------------------------------------------------------------------------
[INFO] Building Tweeter
[INFO]    task-segment: [clean, verify]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] Deleting directory /Users/johnsmart/Projects/wakaleo-training/tdd-traini
ng/lab-solutions/tweeter/target
[INFO] [easyb:test {execution: default}]
[INFO] /Users/johnsmart/Projects/wakaleo-training/tdd-training/lab-solutions/tw
eeter/src/test/easyb does not exists.  Skipping easyb testing
[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
[INFO] ------------------------------------------------------------------------
[INFO] Building Tweeter domain model
[INFO]    task-segment: [clean, verify]
[INFO] ------------------------------------------------------------------------
[INFO] [clean:clean {execution: default-clean}]
[INFO] Deleting directory /Users/johnsmart/Projects/wakaleo-training/tdd-traini
ng/lab-solutions/tweeter/tweeter-core/target
lures: 0, Errors: 0, Skipped: 0
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Tweeter ............................................... SUCCESS [3.266s]
[INFO] Tweeter domain model .................................. SUCCESS [8.338s]
[INFO] Tweeter service layer ................................. SUCCESS [1.830s]
[INFO] Tweeter web application ............................... SUCCESS [20.185s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 34 seconds
[INFO] Finished at: Tue Jan 05 12:21:04 NZDT 2010
[INFO] Final Memory: 63M/123M
[INFO] ------------------------------------------------------------------------
2010-01-05 12:21:04.559::INFO:  Shutdown hook executing
2010-01-05 12:21:05.062:/tweeter-web:INFO:  Closing Spring root WebApplicationC
ontext
2010-01-05 12:21:05.064::INFO:  Shutdown hook complete

Nope, no downloads there. That went pretty well, but the example might have been a bit simple. So let's check this with a medium-size (around 32000 lines of code) real-world project (an old legacy one, to boot!):

$ mvn verify
[INFO] Scanning for projects...
[INFO] Reactor build order: 
[INFO]   BNBGlobal parent module
[INFO]   BNBGlobal localization utilities
[INFO]   BNB Global Core Application
[INFO]   BNB Global Web Application
[INFO]   BNBGlobal aggregator module
[INFO] ------------------------------------------------------------------------
[INFO] Building BNBGlobal parent module
[INFO]    task-segment: [verify]
[INFO] ------------------------------------------------------------------------
[INFO] [enforcer:enforce {execution: enforce-java}]
[INFO] [site:attach-descriptor {execution: default-attach-descriptor}]
[INFO] Preparing source:jar
[WARNING] Removing: jar from forked lifecycle, to prevent recursive invocation.
[INFO] [enforcer:enforce {execution: enforce-java}]
[INFO] [source:jar {execution: default}]
[INFO] NOT adding sources to attached artifacts for packaging: 'pom'.
[INFO] ------------------------------------------------------------------------
[INFO] Building BNBGlobal localization utilities
[INFO]    task-segment: [verify]
[INFO] ------------------------------------------------------------------------
[INFO] [enforcer:enforce {execution: enforce-java}]
[INFO] [groovy:generateStubs {execution: default}]
[INFO]  No sources found for Java stub generation
[INFO] [resources:resources {execution: default-resources}]
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [groovy:compile {execution: default}]
[INFO]  No sources found to compile
[INFO] [groovy:generateTestStubs {execution: default}]
[INFO]  No sources found for Java stub generation
[INFO] [resources:testResources {execution: default-testResources}]
[INFO] Copying 24 resources
[INFO] [compiler:testCompile {execution: default-testCompile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [groovy:testCompile {execution: default}]
[INFO]  No sources found to compile
[INFO] [surefire:test {execution: default-test}]
[INFO] Surefire report directory: /Users/johnsmart/Projects/bnbglobal/bnbglobal
-l10n/target/surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
....
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] BNBGlobal parent module ............................... SUCCESS [3.378s]
[INFO] BNBGlobal localization utilities ...................... SUCCESS [15.495s]
[INFO] BNB Global Core Application ........................... SUCCESS [23.054s]
[INFO] BNB Global Web Application ............................ SUCCESS [26.336s]
[INFO] BNBGlobal aggregator module ........................... SUCCESS [0.112s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 9 seconds
[INFO] Finished at: Wed Jan 06 16:22:07 NZDT 2010
[INFO] Final Memory: 92M/179M
[INFO] ------------------------------------------------------------------------

Hmmm, no updates in sight there either. Just to make sure that my local repository manager wasn't interfering with the process, somehow, I also ran the same tests with no settings.xml in my .m2 directory, with (wait for it!) exactly the same result! So it looks like this one is well and truly busted - Maven does not check for updates, for SNAPSHOT dependencies, for plugins or for anything else, for each build. At most it checks for SNAPSHOT updates once a day. It checks for unversioned plugins once a day, and not at all for versioned plugins (a best practice). And in Maven 3, it only checks for updates if you explicitly ask it to.

Next time we'll take a look at another Maven Myth: Maven requires an internet connection to delete a directory.

(The title and some of the images of this blog were of course shamelessly stolen from the great and highly scientific MythBusters TV series.)

Tags See All Tags Add New Tag...

Please Enter New Tags Separated By Comma's
  Or Close

Java 

Trackback(0)
Comments (4)Add Comment
0
Snapshot update time
written by onekilo79, January 06, 2010
I was asked this exact question a few weeks ago. More specifically about SNAPSHOTs and when they are updated. Searched for the answer and found out what you have stated. The information I found said it does the update at midnight local time, but can be configured.

When using m2eclipse it is useful to ensure that the Update Maven projects on startup is not checked in Eclipse.
0
Very good post
written by Emmanuel Lécharny, January 07, 2010
That is the most interesting post about maven so far in months. When you read rants like http://bit.ly/540y1V, you wonder why people consider ignorance as a valid excuse... May be because some simple facts need to be nailed with post like this one !
0
Nice but unfortunate post.
written by mavendude, January 07, 2010
It's a shame took to time to respond to that garbage Kent posted online. It was a scathing temper tantrum full of flat out lies (with a little opinion). Refuting that article is like trying to explain something to Kanye West, except Kent isn't necessarily as talented as Kanye.

Roll your own and/or Ant is like saying we shouldn't buy cars but build them from scratch, starting with vulcanizing the rubber for the tires.
0
But there is a maven issue ...
written by Arnaud, January 07, 2010
In fact this is not a myth when you encounter MNG-3283 bug

Maven tries to download artifacts it will construct. Thus when it is a SNAPSHOT and you have a repository with them deployed automatically it will try to download them. If this is during a release, it fails because it won't find released artifacts you'll create. This is a problem in maven core which doesn't allow in 2.x to resolve dependencies without downloading artifacts.

This issue occurs when we use the enforcer, the javadoc and some others plugins (issues for these plugins are linked in MNG-3283)

Cheers,

Write comment

security code
Write the displayed characters


busy