1. Object Oriented and beyond
Maven 2 in the real world
Carlo Bonamico
carlo.bonamico@gmail.com
JUG Genova
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
2. Maven2: love it or hate it?
Widespread build platform
β
used by many open source and commercial projects
β
PROs
β
automatic dependency management
β
good tool/IDE support
β
automate the entire build life cycle
β
highly configurable also...
β
lots of tutorials
CONs on simple cases,
β
less documentation
on complex builds
highly configurable :-)
β
too much XML...
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
3. Presentation goals
Maven can be your friend (and save lots of time!)
β
if you
β
learn it and understand it
β
use it in the right way
β
My talk is about how to maximize usefulness and
β
efficiency
while minimizing complexity & overhead
β
Sharing real world experience
β
in designing and managing the build process for
β
several large projects (>20 modules, >100 kLoc)
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
4. Part 1
Maven2 in 5 minutes
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
5. Maven2 in 5 minutes
Maven is a modular automation system built
β
around 4 main elements
repository
POM
Maven
Plugins
src
input: project src/resources + POM
β
output: tested and packaged artifact
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
6. Maven in 5': the POM
The Project Object Model describes
β
project coordinates
β
groupId: net.juggenova
artifactId: sample
project type
β
version: 1.0
packaging (JAR, WAR, EAR, POM)
β
source structure
β
build phases
β
standard + custom
β
dependencies
β
plugins
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
7. Maven in 5': build lifecycle
Default life cycle Every goal implies all
β β
the previous ones
validate
β
generate-sources
β
mvn compile
β
process-resources
β
actually executes
β
compile
β
validate
β
test-compile
β
generate-sources
β
test
β
process-resource
β
package
β
compile
β
integration-test
β
verify
β
Stand-alone goals
β
install
β
deploy
β
mvn scm:update
β
(some skipped for clarity)
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
8. Maven in 5':
Dependency Management
Dependencies
β
include all external libraries and files needed to
β
completely assemble the output
JARs, WARs, ZIPs, POMs
β
are versioned
β
can be transitive
β
e.g. include just spring, get commons-logging
β
automatically
Conflict resolution mechanism
β
determines the version to be used when a jar is
β
included multiple times
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
9. Maven in 5': repositories
Maven repository
β
a structured store containing artifacts (JAR, WAR, ZIP...)
β
Maven uses at leas two
β
local repository β on your PC
β
central repository β http://repo1.maven.org/maven2/
β
Three types of repositories
β
local repository
plain filesystem folder
β
${user.home}/
folder served by HTTP daemon
β
.m2/repository
populated via SCP/FTP/WEBDAV
β
full βintelligentβ repository (with indexing, search, cache, ...)
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
10. From code to repo (and back)
deploy
install remote
repository
local
repository
package central
resolve repository
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
11. Part 2
Effective maven2
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
12. Getting the most out of Maven
Good old sw engineering principles still apply!
β
Don't repeat yourself
β
things
the DRY principle
β always change
in a project
reduce time, effort, maintenance
β
minimize the impact of changes
β
Separate concerns
β
Automate as much as possible
β
Use the right tools (plugins & repositories)
β
Keep the build fast
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
13. How to minimize XML
Exploit the three main POM relationships
β
inheritance, aggregation, dependency
β
This is a valid (and working) maven POM
β
<project xmlns=quot;...quot; xmlns:xsi=quot;...quot;
β
xsi:schemaLocation=quot;...quot;>
β <modelVersion>4.0.0</modelVersion>
β <groupId>net.juggenova.sample</groupId>
β <artifactId>minimal</artifactId>
β <version>1.0</version>
</project>
β
How can this work?
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
14. The Super POM
Implicitely, all POMs inherit from the Super POM
β
see http://maven.apache.org/pom.html
β
Defines Super
β
POM
standard directory structure
β
default plugins & repo
β
your
where it is? inside mvn jars POM
β
how to check it?
β
mvn help:effective-pom
β
Convention over Configuration
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
15. The Super-POM
<repos itories >
<repos itory>
<id>central</id>
<name>Maven R epos itory S witchboard</name>
<url>http://repo1.maven.org /maven2</url>
</repos itory>
</repos itories >
<build>
<s ourceDirectory>s rc/main/java</s ourceDirectory>
<tes tS ourceDirectory>s rc/tes t/java</tes tS ourceDirectory>
<outputDirectory>targ et/clas s es </outputDirectory>
...
<res ources >
<res ource>
<directory>s rc/main/res ources </directory>
</res ource>
</res ources >
<tes tR es ources >...</tes tR es ources >
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
16. The Super-POM
<plug inManag ement>
<plug ins >
<plug in>
<artifactId>maven-as s embly-plug in</artifactId>
<vers ion>2.2-beta-1</vers ion>
</plug in>
<plug in>
<artifactId>maven-compiler-plug in</artifactId>
<vers ion>2.0.2</vers ion>
</plug in>
...
</plug ins >
</plug inManag ement>
</build>
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
17. Parent POM: make you own
Create a POM defining your project conventions
β
and tools
additional resource directories
β
default plugin configuration
β
e.g. custom configuration for maven-compiler-plugin
β
standard libraries
β
e.g. default spring version with
β
<dependencyManagement>
β
repositories and deployment config
β
e.g. your company repository with
β
<distributionManagement>
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
18. net.juggenova.sample:parent
<build>
<s ourceDirectory>java/s rc</s ourceDirectory>
...
<plug inManag ement>
<plug ins >
<plug in>
<g roupId>org .apache.maven.plug ins </g roupId>
<artifactId>maven-compiler-plug in</artifactId>
<config uration>
<s ource>1.6</s ource>
<targ et>1.6</targ et>
</config uration>
</plug in>
<plug in>
<artifactId>maven-s urefire-plug in</artifactId>
<config uration>...</config uration>
</plug in>
</plug ins >
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
19. Parent POM: use it
Reference the parent at the beginning of a POM
β
<parent>
β
β <artifactId>parent</artifactId>
β <groupId>net.juggenova.sample</groupId>
β <version>1.1</version>
β <relativePath>../parent</relativePath>
</parent>
β
Useful
β
if you have many similar projects/components
β
to separate responsibilities between senior and
β
junior developers
to encapsulate company-wide settings
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
20. Issues and suggestions
Main issue: children must reference parent
β
version explicitely
strong dependency! (as usual with inheritance)
β
there is no <version>LATEST</version> or
β
<version>[1.0,)</version> for the parent
if you change the parent, must update ALL children
β
So, avoid putting in the parent things that change
β
your project modules versions
β
developer/machine-specific settings
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
21. Suggestion
Separate things that change
from things that stay the same
Bruce Eckel
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
22. Dependency POMs
Maven2 supports compile (default)
β β
transitive your libs
β
dependencies
test
β
controlled by a
β
junit, spring-test
β
consistent use of the
provided
<scope> tag β
servlet-api
β
runtime
β
library minimize them!
log4j
your POM β
POM
system
β
tools.jar
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
23. Issues and suggestions
Good old encapsulation / minimize coupling
β
minimize dependencies
β
minimize visibility
β
Can also define codeless POMs, which only
β
contain a group of other dependencies
declare with
β
<packaging>pom</packaging>
used with
β
<dependency>...
β
β <type>pom</type>
</dependency>
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
24. Dependency Management
Several libraries are often used in many modules
β
commons-logging, spring, servlet-api,...
β
avoid repeating their version everywhere in POMs
β
Apply DRY & separation of concerns
β
which version to use in the parent/main POM
β
<dependencyManagement> (artifact, group, version)
β
whether to use it
β
<dependency> (artifact, group only) </dependency>
β
Tip: <dependencyManagement> is also effective in
β
overriding versions coming from transitive dependencies
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
25. Aggregation
Multimodule projects
β
every goal is repeated on
β
all modules by the reactor plugin
mvn clean
β
mvn compile
β
<modules >
modules can be
β
<module>client</module>
children of master <module>s erver</module>
<module>tes t</module>
but not necessarily </modules >
β
module
main POM
POM
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
26. Issues and suggestions
Issue: modules are referenced by folder name
β
beware when checking out or renaming
β
Issue: IDE plugin support is not perfect
β
m2eclipse requires manual refresh of dependencies
β
after configuration changes
also, different classpaths in eclipse and maven when
β
opening a multimodule project as a single project
netbeans only supports separate modules
β
Risk: pom proliferation (think of maintenance)
β
mvn modules vs SVN modules
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
27. Suggestion
Common Reuse Principle
Package together what is used/reused togehter
Robert C. Martin
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
28. Tip: create a βMasterβ POM
A βcomponent listβ POM
β
does not have its own code or settings
β
just an index of all modules to be built
β
it is NOT the parent of the modules
β
Example: the main spring pom which triggers the
β
build of
spring-core
β
spring-mvc
β
spring-test
β
...
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
29. Make it easy to create
new projects
Define an archetype
β
a customizable template for creating a kind of
β
projects (e.g. a web application)
defines POMs, project structure
β
Simple setup with
β
mvn archetype:create-from-project
β
customize with resource filtering
β
${property} references in the archetype
β
Use http://appfuse.org
β
library of pre-assembled archetypes
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
30. Part 3
Automate the entire build
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
31. Automate the entire build
Build means much more than compile!
β
Avoid manual steps!
β
copy, rename, deploy to a test server...
β
pass configuration information
β
Automatically process resources
β
copy and filter configuration files, CSS, HTML, properties
β
Share resources across projects
β
package them as jar/zip
β
reuse them in a war project with jar/zip/war overlays
β
http://maven.apache.org/plugins/maven-war-plugin/overlays.html
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
32. Assembly plugin
Creates zips/jars containing any kind of resource
β
project sources
β
common files
β
XSDs
β
β html/CSS
β templates
http://maven.apache.org/plugins/maven-assembly-plugin
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
33. Preview and test webapps
with the Jetty plugin
Run a webapp directly from source folders
β
mvn jetty:run
β
Advantages
β
very fast
β
resource changes are visible without restart
β
automatic redeploy after code changes
β
http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin
β
Now a mvn glassfish:run goal is also available
β
full JEE 5.0 support
β
https://maven-glassfish-plugin.dev.java.net/
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
34. Automate deployment
Deploy to an application server with cargo
β
can even download, install and run a full Jboss
β
instance for testing purposes
http://cargo.codehaus.org/
β
Write custom ssh-based scripts using the ssh/scp
β
ant tasks within the maven-antrun-plugin
transfer files to test servers
β
launch administration scripts
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
35. Integrate with the IDE
E.g. Eclipse plugin (m2eclipse)
β
http://m2eclipse.sonatype.com
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
36. Use a group repository
Why your own?
β
Within a Team
β
deploy and share your project artifacts
β
so that other developers do not have to rebuild them
β
βmavenizeβ external jars which miss a POM
β
centrally configure and control which repositories
β
and artifacts are used
cache dependencies
β
available when internet connection breaks
β
faster download times
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
37. Sonatype Nexus repository
Powerful web-based console
β
and REST API
β
Lightweight
β
Easily upload artifacts via HTTP
β
Quickly search for jars
β
with the included index
β
Download from http://nexus.sonatype.org/
β
unzip and run!
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
38. settings.xml: Mirror definition
Team repository in addition to central
β
<repository>
β
β <id> set </id>
β <url> http://server:8080/repository </url>
</repository>
β
Team repository as a mirror of central (or others)
β
<mirror>
β
β <id> central </id>
β <url> http://server:8080/repository</url>
β <mirrorOf> central </mirrorOf>
</mirror>
β
Team repository as the only one
β
<mirror>
β
β <id> ... </id> <url> ... </url>
β <mirrorOf> * </mirrorOf>
</mirror>
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
39. Part 4
Troubleshooting
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
40. Build troubleshooting
Verify POM structure
β
mvn validate
β
Verify actually used dependencies
β
mvn dependency:tree
β
β -Dinclude=spring
Verify the full POM
β
mvn help:effective-pom
β
m2eclipse plugin
β
Moreover,
β
keep a consistent naming scheme to prevent typos
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
41. Debug/Log
Run mvn with
β
-e (print Exception stacktraces)
β
-X (print debug info)
β
POM information can be accessed at runtime!
β
META-INF/<group>/<artifact>/pom.properties
β
groupId
β
artifactId R es ource[] res ources = applicationC ontext
β
.g etR es ources (quot; clas s path*:M ETA-INF/mavenquot;+
version quot; /**/pom.properties quot; );
β
META-INF/../pom.xml for (R es ource r : res ources ) {
β
Properties p = new Properties ();
p.load(r.g etInputS tream());
full POM info
β
artifact = p.g etProperty(quot; artifactIdquot; );
vers ion = p.g etProperty(quot; vers ionquot; );
}
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
42. Add a timestamp to your builds
Automatically define a timestamp property
β
use it in resources or test properties
β
<plugin>
β
β <groupId>org.codehaus.mojo</groupId>
β <artifactId>buildnumber-maven-
plugin</artifactId>
β <executions> ... </executions>
β <configuration>
<format>{0,date,yyyy-MM-dd HH:mm:ss}</format>
β
<items>
β
<item>timestamp</item>
β
</items>
β
β </configuration>
</plugin>
http://mojo.codehaus.org/buildnumber-maven-plugin
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
43. Part 5
Keep the build fast
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
44. Keep the build fast
Ideally, zero-time build
β
http://blog.carbonfive.com/2008/09/java/make-the-
β
things-you-do-often-fast-and-easy
The more often a task is performed, the more its
β
optimization improves developer productivity
save time for actual project work
β
Run maven on the latest JDK
β
benefit from JDK 1.6 fast startup times/optimizations
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
45. Eclipse compiler
Faster than JDK's javac
β
also provides more warnings (unused variables, generics
β
misuse...)
<plugin>
β
<artifactId>maven-compiler-plugin</artifactId>
β
<configuration>
β
<compilerId>eclipse</compilerId>
β
</configuration>
β
<dependencies>
β
<dependency>
β
<groupId>org.codehaus.plexus</groupId>
β
<artifactId>plexus-compiler-eclipse</artifactId>
β
<version>1.5.2</version>
β
</dependency>
β
</dependencies>
β
</plugin>
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
46. Unit test vs integration tests
Run unit tests often
β
must not take half an hour! or else developers will
β
just skip them
-Dmaven.test.skip=true
β
Separate unit tests from integration tests
β
unit tests in every project/module
β
fast
β
run at every build (within mvn install)
β
integration and acceptance tests in dedicated
β
module
run after major changes, and/or on build servers
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
47. Remove useless build elements
POM, plugin and dependency list keeps growing
β
Periodically review the POM
β
Remove unused dependencies
β
copying them around means more slow disk accesses
β
mvn dependency:analyze
β
Remove unused plugins
β
move them to optionally-activated profiles
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
48. Speed-up day-to-day tasks
Define a default goal
β
<defaultGoal>compile</defaultGoal>
β
then just run
β
mvn
β
Use the right goal
β
avoid a full mvn install if you just need a mvn test
β
Define shell aliases for common tasks
β
Use a CI server that reads and reuses mvn
β
configuration such as hudson
https://hudson.dev.java.net
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
49. Incrementally build large
multimodule projects
Reactor plugin
β
http://maven.apache.org/plugins/maven-reactor-plugin/
β
manages dependencies and build order
β
resume a build from the last failed module
β
mvn reactor:resume
β
build a project and all its dependencies
β
mvn reactor:make
β
build all modules which have an SVN status of changed
β
mvn reactor:make-scm-changes
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
50. References
Maven official site
β
http://maven.apache.org
β
Best online book
β
Maven 2 β The Definitive Guide
β
http://books.sonatype.com/maven-book
β
JavaWorld articles
β
Introduction to maven2
β
http://www.javaworld.com/javaworld/jw-12-2005/jw-1205-maven.html
β
POM
β
http://www.javaworld.com/javaworld/jw-05-2006/jw-0529-maven.html
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009
51. Thanks for your attention!
Learn more at
β
http://www.carlobonamico.com/blog
β
http://juggenova.net
β
presentations, demos, code samples
β
Play with the samples
β
http://juggenova.net/code-samples/
β
Contact me at
β
carlo.bonamico@gmail.com
β
Related reading: Continuous Integration with Hudson
β
http://www.slideshare.net/carlo.bonamico/continuous-integration-with-hudson
β
Carlo Bonamico - carlo.bonamico@gmail.com β JUG Genova
Javaday Roma III Edizione β 24 gennaio 2009