Top Banner
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
51

Maven 2 in the real world

May 10, 2015

Download

Technology

Carlo Bonamico

How to effectively employ Maven2 on large scale projects
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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