More Apache Maven Best Practices

Post on 28-Nov-2014

10.281 views 7 download

description

Second presentation on a collection of best practices given at ApacheCon US 2008

Transcript of More Apache Maven Best Practices

More Apache MavenBest Practices

1

Brett Porter - brett@apache.org

1

More Apache MavenBest Practices

1

Brett Porter - brett@apache.org

1

Welcome Back

2

This time last year...Apache Maven Best PracticesSlides are available online• http://blogs.exist.com/bporter/

But wait, there’s more!

2

Recap

3

3

EnvironmentSet up your environment in advanceA repository manager is a must

4

4

Keep the POM simpleWrite your build like you write your code

Keep it Simple

5

5

Keep it PortableKeep the build portableAvoid hard codingMake artifacts portable and minimize resource filtering

6

6

Keep it ReproducibleBefore releasing, make sure the build is reproducibleFirst, it must be portableLock downversionsLock downenvironmentalvariations

7

7

The Enforcer

8

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-alpha-4</version> <executions> <execution> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <requirePluginVersions> <banLatest>true</banLatest> <banRelease>true</banRelease> </requirePluginVersions> </rules> </configuration> ...

8

The Enforcer

9

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-alpha-4</version> <executions> <execution> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <requirePluginVersions> <banLatest>true</banLatest> <banRelease>true</banRelease> </requirePluginVersions> </rules> </configuration> ...

9

The Enforcer

9

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-alpha-4</version> <executions> <execution> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <requirePluginVersions> <banLatest>true</banLatest> <banRelease>true</banRelease> </requirePluginVersions> </rules> </configuration> ...

<rules> <requirePluginVersions> <banLatest>true</banLatest> <banRelease>true</banRelease> </requirePluginVersions></rules>

9

The EnforcerHelp ensure build will be reproducibleBased on rules

force specific plugin versionsban snapshotsglobal exclusionsforce Maven/Java/OS versioncan write your own

10

10

Release Early and OftenMake sure releases are quick, easy, and automatedUse the Maven/Continuum tools to help

11

11

And Now...Dependency managementIntegration testingMaven sites and reportingPlugin development

12

12

Dependency Management

13

13

Dependencies EverywhereTransitive dependencies are very convenient...

... until you get bitten by bad metadataYou wind up witha tree of artifactsyou may or maynot be using

14

14

Troubleshoot Dependenciesmvn dependency:tree

or equivalent Eclipse integration

15

[INFO] org.example.maven:example-webapp:war:1.2-SNAPSHOT[INFO] +- junit:junit:jar:3.8.1:test[INFO] +- org.apache.struts:struts2-core:jar:2.0.5:compile[INFO] | +- opensymphony:xwork:jar:2.0.0:compile[INFO] | +- org.apache.struts:struts2-api:jar:2.0.5:compile[INFO] | +- freemarker:freemarker:jar:2.3.8:compile[INFO] | +- ognl:ognl:jar:2.6.9:compile[INFO] | \- commons-logging:commons-logging:jar:1.0.4:compile[INFO] +- org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile[INFO] | \- opensymphony:sitemesh:jar:2.2.1:compile[INFO] +- org.apache.struts:struts2-spring-plugin:jar:2.0.5:compile[INFO] | +- org.springframework:spring-beans:jar:2.0.1:compile[INFO] | +- org.springframework:spring-core:jar:2.0.1:compile[INFO] | +- org.springframework:spring-context:jar:2.0.1:compile[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile[INFO] | \- org.springframework:spring-web:jar:2.0.1:compile[INFO] +- javax.servlet:servlet-api:jar:2.4:provided[INFO] +- javax.servlet:jsp-api:jar:2.0:provided[INFO] +- commons-fileupload:commons-fileupload:jar:1.1.1:compile[INFO] | \- commons-io:commons-io:jar:1.1:compile[INFO] +- uk.ltd.getahead:dwr:jar:1.1-beta-3:compile[INFO] +- org.example.maven:example-model:jar:1.2-SNAPSHOT:compile[INFO] \- org.example.maven:example-manager:jar:1.2-SNAPSHOT:compile

15

Troubleshoot Dependenciesmvn dependency:tree

or equivalent Eclipse integration

15

[INFO] org.example.maven:example-webapp:war:1.2-SNAPSHOT[INFO] +- junit:junit:jar:3.8.1:test[INFO] +- org.apache.struts:struts2-core:jar:2.0.5:compile[INFO] | +- opensymphony:xwork:jar:2.0.0:compile[INFO] | +- org.apache.struts:struts2-api:jar:2.0.5:compile[INFO] | +- freemarker:freemarker:jar:2.3.8:compile[INFO] | +- ognl:ognl:jar:2.6.9:compile[INFO] | \- commons-logging:commons-logging:jar:1.0.4:compile[INFO] +- org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile[INFO] | \- opensymphony:sitemesh:jar:2.2.1:compile[INFO] +- org.apache.struts:struts2-spring-plugin:jar:2.0.5:compile[INFO] | +- org.springframework:spring-beans:jar:2.0.1:compile[INFO] | +- org.springframework:spring-core:jar:2.0.1:compile[INFO] | +- org.springframework:spring-context:jar:2.0.1:compile[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile[INFO] | \- org.springframework:spring-web:jar:2.0.1:compile[INFO] +- javax.servlet:servlet-api:jar:2.4:provided[INFO] +- javax.servlet:jsp-api:jar:2.0:provided[INFO] +- commons-fileupload:commons-fileupload:jar:1.1.1:compile[INFO] | \- commons-io:commons-io:jar:1.1:compile[INFO] +- uk.ltd.getahead:dwr:jar:1.1-beta-3:compile[INFO] +- org.example.maven:example-model:jar:1.2-SNAPSHOT:compile[INFO] \- org.example.maven:example-manager:jar:1.2-SNAPSHOT:compile

<exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion></exclusions>

15

Troubleshoot Dependenciesmvn dependency:tree

or equivalent Eclipse integration

15

[INFO] org.example.maven:example-webapp:war:1.2-SNAPSHOT[INFO] +- junit:junit:jar:3.8.1:test[INFO] +- org.apache.struts:struts2-core:jar:2.0.5:compile[INFO] | +- opensymphony:xwork:jar:2.0.0:compile[INFO] | +- org.apache.struts:struts2-api:jar:2.0.5:compile[INFO] | +- freemarker:freemarker:jar:2.3.8:compile[INFO] | +- ognl:ognl:jar:2.6.9:compile[INFO] | \- commons-logging:commons-logging:jar:1.0.4:compile[INFO] +- org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile[INFO] | \- opensymphony:sitemesh:jar:2.2.1:compile[INFO] +- org.apache.struts:struts2-spring-plugin:jar:2.0.5:compile[INFO] | +- org.springframework:spring-beans:jar:2.0.1:compile[INFO] | +- org.springframework:spring-core:jar:2.0.1:compile[INFO] | +- org.springframework:spring-context:jar:2.0.1:compile[INFO] | | \- aopalliance:aopalliance:jar:1.0:compile[INFO] | \- org.springframework:spring-web:jar:2.0.1:compile[INFO] +- javax.servlet:servlet-api:jar:2.4:provided[INFO] +- javax.servlet:jsp-api:jar:2.0:provided[INFO] +- commons-fileupload:commons-fileupload:jar:1.1.1:compile[INFO] | \- commons-io:commons-io:jar:1.1:compile[INFO] +- uk.ltd.getahead:dwr:jar:1.1-beta-3:compile[INFO] +- org.example.maven:example-model:jar:1.2-SNAPSHOT:compile[INFO] \- org.example.maven:example-manager:jar:1.2-SNAPSHOT:compile

<rules> <bannedDependencies> <excludes> <exclude>commons-logging:commons-logging</exclude> </excludes> </bannedDependencies></rules>

<exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion></exclusions>

15

Don’t Add to the ProblemBe careful with your own dependencies

Specify only what you needSpecify scopeUse optional if you must

Use dependencyManagement to:coerce Maven to use a particular versionenforce consistency within a project

16

16

Only What You Needmvn dependency:analyze

find out what you’re using but not declaringfind out what you’re declaring but not using

17

[WARNING] Used undeclared dependencies found:[WARNING] opensymphony:xwork:jar:2.0.0:compile[WARNING] Unused declared dependencies found:[WARNING] org.apache.struts:struts2-spring-plugin:jar:2.0.5:compile[WARNING] javax.servlet:jsp-api:jar:2.0:provided[WARNING] commons-fileupload:commons-fileupload:jar:1.1.1:compile[WARNING] javax.servlet:servlet-api:jar:2.4:provided[WARNING] org.apache.struts:struts2-core:jar:2.0.5:compile[WARNING] org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile[WARNING] uk.ltd.getahead:dwr:jar:1.1-beta-3:compile

17

Integration Testing

18

18

“Integration” TestingCovers any type of testing beyond unit

integration testingfunctional testing, etc.

Unfortunately, an afterthought in Maven 2.0.x

at least in the lifecycle

19

19

PatternsTests in a separate moduleTests in same projectUse of profiles applies to botheg. Maven

Plugin ITs are in the pluginCore ITs are separate

20

20

Separate ProjectMost common patternIf you are testing multiple modules, use a separate project

21

21

Separate Projectcreate a parallel moduleuse the regular src/test/java directoryadd a dependency on the module(s) being testedenable the module in a profile

if a profile is necessary

22

22

Separate Projectcreate a parallel moduleuse the regular src/test/java directoryadd a dependency on the module(s) being testedenable the module in a profile

if a profile is necessary

22

<profile> <id>run-its</id> <modules> <module>integration-tests</module> </modules></profile>

22

Testing in the Same ProjectGood for framework examples and small projectsTwo alternatives

separate directory, redeclare both compilation and test plugins• eg src/it

same test directory, test exclusions• eg **/selenium/**

Include the tests in a profile

23

23

Example: Selenium

24

24

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/selenium/**</exclude> </excludes> </configuration></plugin>

Example: Selenium

24

24

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/selenium/**</exclude> </excludes> </configuration></plugin>

<profile> <id>selenium</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <executions> <execution> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <includes> <include>**/selenium/**/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build></profile>

Example: Selenium

24

24

<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/selenium/**</exclude> </excludes> </configuration></plugin>

<profile> <id>selenium</id> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <executions> <execution> <phase>integration-test</phase> <goals> <goal>test</goal> </goals> <configuration> <includes> <include>**/selenium/**/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build></profile>

Example: Selenium

24

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>selenium-maven-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <phase>pre-integration-test</phase> <goals> <goal>start-server</goal> </goals> </execution> </executions> <configuration> <background>true</background> </configuration></plugin>

24

Maven Sites and Reporting

25

25

Two technologiesreportingrendering

They aren’t the same!They work together

... but can be used independently

... and should be for different tasks

Maven Sites

26

26

Site TipsAvoid reports on documentation sites

some minimal project reports, like mailing lists, source repository may be relevant

Use site inheritanceUse versioning in the URL

for version specific usage documentationespecially for developer reference site

Include release notes in the versioned usage documentation

27

27

Set up what you’ll use!don't create reports with thousands of issues

It won’t be used if...too much informationirrelevant information

Don’t settle for thedefault settings

Report Tips

28

28

Report TipsUse active checks, not passive reports

fail the build!Use profiles if they are time consuming

run them in continuous integrationdevelopers can use IDE integration

Have a centralized location to deploy reports

visualize problems, and errors under the build failure threshold

29

29

Plugin Development

30

30

Don’t Fear ScriptingSometimes it is easier to use a script for short, one-off, customizations

antrun pluginjruby, groovy plugin, etc.

If you might use it twice, consider writing a plugin

31

31

Plugin DevelopmentIt isn’t the big deal you think it isCan be written in Java, Ruby, Groovy, ...Plugins are as easy to write as any other module

though they still lack the quick “run and test” scenario of most scripting solutions

32

32

Plugin TipsWrite functionality in components, with the Mojo as a “wrapper”

easier to test and reusethe theory of mojos as pojos isn’t as realistic due to the current wiring

Minimize Maven API dependencies and component exposure

eg, use maven-artifact, not maven-coreMinimize dependencies in general

all builds have to download them!33

33

Final WordDo as we say...

... but not as we doMaven fails to implement many of these practices in various projects

We learned the hard way!It can be really hard to find time to go back and fix it later

34

34

Questions?

35

Brett Porter - brett@apache.org

35

Questions?

35

Brett Porter - brett@apache.org

35