maven 2 in the real world

51
Carlo Bonamico - [email protected] – JUG Genova Javaday Roma III Edizione – 24 gennaio 2009 Object Oriented and beyond Maven 2 in the real world Carlo Bonamico [email protected] JUG Genova

Upload: carlo-bonamico

Post on 10-May-2015

13.235 views

Category:

Technology


0 download

DESCRIPTION

How to effectively employ Maven2 on large scale projects

TRANSCRIPT

Page 1: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Object Oriented and beyond

Maven 2 in the real world

Carlo [email protected]

JUG Genova

Page 2: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

● CONs– highly configurable :-)– too much XML...

also... lots of tutorials

on simple cases, less documentation

on complex builds

Page 3: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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)

Page 4: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Part 1

Maven2 in 5 minutes

Page 5: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Maven2 in 5 minutes

● Maven is a modular automation system built around 4 main elements

– input: project src/resources + POM – output: tested and packaged artifact

Maven

POM

repository

Pluginssrc

Page 6: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Maven in 5': the POM

● The Project Object Model describes– project coordinates– project type

● packaging (JAR, WAR, EAR, POM)– source structure– build phases

● standard + custom– dependencies– plugins

groupId: net.juggenovaartifactId: sample

version: 1.0

Page 7: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Maven in 5': build lifecycle

● Default life cycle– validate – generate-sources– process-resources– compile – test-compile – test– package – integration-test – verify – install – deploy

– (some skipped for clarity)

● Every goal implies all the previous ones

– mvn compile– actually executes

– validate – generate-sources– process-resource– compile

● Stand-alone goals– mvn scm:update

Page 8: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 9: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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– plain filesystem folder– folder served by HTTP daemon

● populated via SCP/FTP/WEBDAV– full “intelligent” repository (with indexing, search, cache, ...)

local repository

${user.home}/.m2/repository

Page 10: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

From code to repo (and back)

local repository

central repository

remoterepository

install

deploy

packageresolve

Page 11: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Part 2

Effective maven2

Page 12: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Getting the most out of Maven

● Good old sw engineering principles still apply!● Don't repeat yourself

– the DRY principle● 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

things always change

in a project

Page 13: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

How to minimize XML

● Exploit the three main POM relationships– inheritance, aggregation, dependency

● This is a valid (and working) maven POM– <project xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">

● <modelVersion>4.0.0</modelVersion>● <groupId>net.juggenova.sample</groupId>● <artifactId>minimal</artifactId>● <version>1.0</version>

– </project>● How can this work?

Page 14: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

The Super POM

● Implicitely, all POMs inherit from the Super POM– see http://maven.apache.org/pom.html

● Defines– standard directory structure– default plugins & repo

– where it is? inside mvn jars– how to check it?

– mvn help:effective-pom● Convention over Configuration

SuperPOM

yourPOM

Page 15: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

The Super-POM

<repos itories> <repos itory> <id>central</id> <name>Maven Repos itory S witchboard</name> <url>http://repo1.maven.org/maven2</url> </repos itory> </repos itories> <build> <sourceDirectory>src/main/java</sourceDirectory> <tes tS ourceDirectory>src/tes t/java</tes tS ourceDirectory> <outputDirectory>target/classes</outputDirectory> ... <resources> <resource> <directory>src/main/resources</directory> </resource> </resources> <tes tResources>...</testResources>

Page 16: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

The Super-POM

<pluginManagement> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <vers ion>2.2-beta-1</vers ion> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <vers ion>2.0.2</vers ion> </plugin>

... </plugins> </pluginManagement> </build>

Page 17: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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>

Page 18: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

net.juggenova.sample:parent

<build> <sourceDirectory>java/src</sourceDirectory> ... <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId>

<configuration>...</configuration> </plugin> </plugins>

Page 19: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 20: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 21: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Suggestion

Separate things that change from things that stay the same

Bruce Eckel

Page 22: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Dependency POMs

● Maven2 supports transitive dependencies

– controlled by a consistent use of the <scope> tag

● compile (default)– your libs

● test– junit, spring-test

● provided– servlet-api

● runtime– log4j

● system – tools.jar

minimize them!your POM library POM

Page 23: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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>

Page 24: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 25: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Aggregation

● Multimodule projects– every goal is repeated on

all modules by the reactor plugin– mvn clean– mvn compile

– modules can be children of master

● but not necessarily

<modules> <module>client</module> <module>server</module> <module>test</module></modules>

main POM module POM

Page 26: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 27: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Suggestion

Common Reuse Principle

Package together what is used/reused togehter

Robert C. Martin

Page 28: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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– ...

Page 29: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 30: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Part 3

Automate the entire build

Page 31: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 32: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 33: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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/

Page 34: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 35: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Integrate with the IDE

● E.g. Eclipse plugin (m2eclipse)– http://m2eclipse.sonatype.com

Page 36: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 37: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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!

Page 38: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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>

Page 39: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Part 4

Troubleshooting

Page 40: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 41: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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● version

– META-INF/../pom.xml ● full POM info

Resource[] resources = applicationContext .getResources("classpath*:META-INF/maven"+

"/**/pom.properties ");

for (Resource r : resources) { Properties p = new Properties (); p.load(r.getInputS tream());

artifact = p.getProperty("artifactId"); vers ion = p.getProperty("vers ion");

}

Page 42: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 43: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

Part 5

Keep the build fast

Page 44: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 45: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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>

Page 46: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 47: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 48: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 49: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 50: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

Page 51: Maven 2 in the real world

Carlo Bonamico - [email protected] – JUG GenovaJavaday Roma III Edizione – 24 gennaio 2009

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

[email protected]● Related reading: Continuous Integration with Hudson

– http://www.slideshare.net/carlo.bonamico/continuous-integration-with-hudson