More Apache Maven
  Best Practices
Brett Porter - brett@apache.org




                                  1


             ...
More Apache Maven
  Best Practices
Brett Porter - brett@apache.org




                                  1


             ...
Welcome Back
This time last year...
 Apache Maven Best Practices
 Slides are available online
  • http://blogs.exist.com/b...
Recap




        3


            3
Environment
Set up your environment in advance
A repository manager is a must




                                 4


   ...
Keep it Simple
Keep the POM simple
Write your build like you write your code




                                    5


 ...
Keep it Portable
Keep the build portable
Avoid hard coding
Make artifacts portable and
minimize resource filtering




   ...
Keep it Reproducible
Before releasing, make sure the build is
reproducible
First, it must be portable
Lock down
versions
L...
The Enforcer
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <ve...
The Enforcer
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <ve...
The Enforcer
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <ve...
The Enforcer
Help ensure build will be reproducible
Based on rules
 force specific plugin versions
 ban snapshots
 global ...
Release Early and Often
Make sure releases are quick, easy,
and automated
Use the Maven/Continuum tools to help




      ...
And Now...
Dependency management
Integration testing
Maven sites and reporting
Plugin development




                    ...
Dependency Management




                  13


                        13
Dependencies Everywhere
Transitive dependencies are very
convenient...
 ... until you get bitten by bad metadata
You wind ...
Troubleshoot Dependencies
mvn dependency:tree
 or equivalent Eclipse integration
    [INFO]   org.example.maven:example-we...
Troubleshoot Dependencies
  mvn dependency:tree
     or equivalent Eclipse integration
         [INFO] org.example.maven:e...
Troubleshoot Dependencies
 mvn dependency:tree
    or equivalent Eclipse integration
         [INFO] org.example.maven:exa...
Don’t Add to the Problem
Be careful with your own dependencies
 Specify only what you need
 Specify scope
 Use optional if...
Only What You Need
 mvn dependency:analyze
    find out what you’re using but not declaring
    find out what you’re decla...
Integration Testing




                      18


                           18
“Integration” Testing
Covers any type of testing beyond unit
 integration testing
 functional testing, etc.
Unfortunately,...
Patterns
Tests in a separate module
Tests in same project
Use of profiles applies to both
eg. Maven
 Plugin ITs are in the...
Separate Project
Most common pattern
If you are testing multiple modules, use
a separate project




                     ...
Separate Project
create a parallel module
use the regular src/test/java directory
add a dependency on the module(s)
being ...
Separate Project
create a parallel module
use the regular src/test/java directory
add a dependency on the module(s)
being ...
Testing in the Same Project
Good for framework examples and
small projects
Two alternatives
 separate directory, redeclare...
Example: Selenium




                    24


                         24
Example: Selenium
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
...
Example: Selenium
<plugin>
        <profile>
  <groupId>org.apache.maven.plugins</groupId>
          <id>selenium</id>
  <...
Example: Selenium
<plugin>
        <profile>
  <groupId>org.apache.maven.plugins</groupId>
          <id>selenium</id>
  <...
Maven Sites and Reporting




                     25


                            25
Maven Sites
Two technologies
 reporting
 rendering
They aren’t the same!
They work together
 ... but can be used independe...
Site Tips
Avoid reports on documentation sites
 some minimal project reports, like mailing
 lists, source repository may b...
Report Tips
Set up what you’ll use!
 don't create reports with thousands of issues
It won’t be used if...
 too much inform...
Report Tips
Use active checks, not passive reports
 fail the build!
Use profiles if they are time consuming
 run them in c...
Plugin Development




                     30


                          30
Don’t Fear Scripting
Sometimes it is easier to use a script for
short, one-off, customizations
 antrun plugin
 jruby, groo...
Plugin Development
It isn’t the big deal you think it is
Can be written in Java, Ruby,
Groovy, ...
Plugins are as easy to ...
Plugin Tips
Write functionality in components, with
the Mojo as a “wrapper”
 easier to test and reuse
 the theory of mojos...
Final Word
Do as we say...
 ... but not as we do
Maven fails to implement many of these
practices in various projects
 We ...
Questions?
Brett Porter - brett@apache.org




                                  35


                                    ...
Questions?
Brett Porter - brett@apache.org




                                  35


                                    ...
Upcoming SlideShare
Loading in...5
×

More Apache Maven Best Practices

8,819

Published on

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

Published in: Technology

More Apache Maven Best Practices

  1. 1. More Apache Maven Best Practices Brett Porter - brett@apache.org 1 1
  2. 2. More Apache Maven Best Practices Brett Porter - brett@apache.org 1 1
  3. 3. Welcome Back This time last year... Apache Maven Best Practices Slides are available online • http://blogs.exist.com/bporter/ But wait, there’s more! 2 2
  4. 4. Recap 3 3
  5. 5. Environment Set up your environment in advance A repository manager is a must 4 4
  6. 6. Keep it Simple Keep the POM simple Write your build like you write your code 5 5
  7. 7. Keep it Portable Keep the build portable Avoid hard coding Make artifacts portable and minimize resource filtering 6 6
  8. 8. Keep it Reproducible Before releasing, make sure the build is reproducible First, it must be portable Lock down versions Lock down environmental variations 7 7
  9. 9. The Enforcer <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 8
  10. 10. The Enforcer <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 9
  11. 11. The Enforcer <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-alpha-4</version> <executions> <execution> <goals> <rules><goal>enforce</goal> </goals> <requirePluginVersions> <configuration> <rules> <banLatest>true</banLatest> <requirePluginVersions> <banLatest>true</banLatest> <banRelease>true</banRelease> <banRelease>true</banRelease> </requirePluginVersions> </requirePluginVersions> </rules> </rules> </configuration> ... 9 9
  12. 12. The Enforcer Help ensure build will be reproducible Based on rules force specific plugin versions ban snapshots global exclusions force Maven/Java/OS version can write your own 10 10
  13. 13. Release Early and Often Make sure releases are quick, easy, and automated Use the Maven/Continuum tools to help 11 11
  14. 14. And Now... Dependency management Integration testing Maven sites and reporting Plugin development 12 12
  15. 15. Dependency Management 13 13
  16. 16. Dependencies Everywhere Transitive dependencies are very convenient... ... until you get bitten by bad metadata You wind up with a tree of artifacts you may or may not be using 14 14
  17. 17. Troubleshoot Dependencies mvn dependency:tree or equivalent Eclipse integration [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 15
  18. 18. Troubleshoot Dependencies mvn dependency:tree or equivalent Eclipse integration [INFO] org.example.maven:example-webapp:war:1.2-SNAPSHOT <exclusions> +- junit:junit:jar:3.8.1:test [INFO] <exclusion> +- org.apache.struts:struts2-core:jar:2.0.5:compile [INFO] [INFO] | +- opensymphony:xwork:jar:2.0.0:compile <groupId>commons-logging</groupId> [INFO] | +- org.apache.struts:struts2-api:jar:2.0.5:compile [INFO] | +- freemarker:freemarker:jar:2.3.8:compile <artifactId>commons-logging</artifactId> [INFO] | +- ognl:ognl:jar:2.6.9:compile </exclusion>| - commons-logging:commons-logging:jar:1.0.4:compile [INFO] </exclusions> +- org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile [INFO] [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 15
  19. 19. Troubleshoot Dependencies mvn dependency:tree or equivalent Eclipse integration [INFO] org.example.maven:example-webapp:war:1.2-SNAPSHOT <exclusions> +- junit:junit:jar:3.8.1:test [INFO] <exclusion> +- org.apache.struts:struts2-core:jar:2.0.5:compile [INFO] [INFO] | +- opensymphony:xwork:jar:2.0.0:compile <groupId>commons-logging</groupId> [INFO] | +- org.apache.struts:struts2-api:jar:2.0.5:compile [INFO] | +- freemarker:freemarker:jar:2.3.8:compile <artifactId>commons-logging</artifactId> [INFO] | +- ognl:ognl:jar:2.6.9:compile </exclusion>| - commons-logging:commons-logging:jar:1.0.4:compile [INFO] </exclusions> +- org.apache.struts:struts2-sitemesh-plugin:jar:2.0.5:compile [INFO] [INFO] | - opensymphony:sitemesh:jar:2.2.1:compile [INFO] +- org.apache.struts:struts2-spring-plugin:jar:2.0.5:compile <rules> [INFO] | +- org.springframework:spring-beans:jar:2.0.1:compile [INFO] | +- org.springframework:spring-core:jar:2.0.1:compile <bannedDependencies> [INFO] | +- org.springframework:spring-context:jar:2.0.1:compile <excludes> [INFO] | | - aopalliance:aopalliance:jar:1.0:compile [INFO] | - org.springframework:spring-web:jar:2.0.1:compile <exclude>commons-logging:commons-logging</exclude> [INFO] +- javax.servlet:servlet-api:jar:2.4:provided </excludes> [INFO] +- javax.servlet:jsp-api:jar:2.0:provided [INFO] +- commons-fileupload:commons-fileupload:jar:1.1.1:compile </bannedDependencies> [INFO] | - commons-io:commons-io:jar:1.1:compile </rules> [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 15
  20. 20. Don’t Add to the Problem Be careful with your own dependencies Specify only what you need Specify scope Use optional if you must Use dependencyManagement to: coerce Maven to use a particular version enforce consistency within a project 16 16
  21. 21. Only What You Need mvn dependency:analyze find out what you’re using but not declaring find out what you’re declaring but not using [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 17
  22. 22. Integration Testing 18 18
  23. 23. “Integration” Testing Covers any type of testing beyond unit integration testing functional testing, etc. Unfortunately, an afterthought in Maven 2.0.x at least in the lifecycle 19 19
  24. 24. Patterns Tests in a separate module Tests in same project Use of profiles applies to both eg. Maven Plugin ITs are in the plugin Core ITs are separate 20 20
  25. 25. Separate Project Most common pattern If you are testing multiple modules, use a separate project 21 21
  26. 26. Separate Project create a parallel module use the regular src/test/java directory add a dependency on the module(s) being tested enable the module in a profile if a profile is necessary 22 22
  27. 27. Separate Project create a parallel module use the regular src/test/java directory add a dependency on the module(s) being tested enable the module in a profile if a profile is necessary <profile> <id>run-its</id> <modules> <module>integration-tests</module> </modules> </profile> 22 22
  28. 28. Testing in the Same Project Good for framework examples and small projects Two 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
  29. 29. Example: Selenium 24 24
  30. 30. Example: Selenium <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <excludes> <exclude>**/selenium/**</exclude> </excludes> </configuration> </plugin> 24 24
  31. 31. Example: Selenium <plugin> <profile> <groupId>org.apache.maven.plugins</groupId> <id>selenium</id> <artifactId>maven-surefire-plugin</artifactId> <build> <configuration> <plugins> <plugin> <excludes> <groupId>org.apache.maven.plugins</groupId> <exclude>**/selenium/**</exclude> <artifactId>maven-surefire-plugin</artifactId> </excludes> <executions> <execution> </configuration> <phase>integration-test</phase> </plugin> <goals> <goal>test</goal> </goals> <configuration> <includes> <include>**/selenium/**/*Test.java</include> </includes> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile> 24 24
  32. 32. Example: Selenium <plugin> <profile> <groupId>org.apache.maven.plugins</groupId> <id>selenium</id> <artifactId>maven-surefire-plugin</artifactId> <build> <configuration> <plugins> <plugin> <excludes> <groupId>org.apache.maven.plugins</groupId> <exclude>**/selenium/**</exclude> <artifactId>maven-surefire-plugin</artifactId> </excludes> <executions> <execution> </configuration> <phase>integration-test</phase> </plugin> <goals> <plugin> <groupId>org.codehaus.mojo</groupId> <goal>test</goal> <artifactId>selenium-maven-plugin</artifactId> </goals> <version>1.0-beta-1</version> <configuration> <executions> <includes> <execution> <include>**/selenium/**/*Test.java</include> <phase>pre-integration-test</phase> </includes> <goals> </configuration> <goal>start-server</goal> </execution> </goals> </executions> </execution> </plugin> </executions> </plugins> <configuration> </build> <background>true</background> </profile> </configuration> </plugin> 24 24
  33. 33. Maven Sites and Reporting 25 25
  34. 34. Maven Sites Two technologies reporting rendering They aren’t the same! They work together ... but can be used independently ... and should be for different tasks 26 26
  35. 35. Site Tips Avoid reports on documentation sites some minimal project reports, like mailing lists, source repository may be relevant Use site inheritance Use versioning in the URL for version specific usage documentation especially for developer reference site Include release notes in the versioned usage documentation 27 27
  36. 36. Report Tips Set up what you’ll use! don't create reports with thousands of issues It won’t be used if... too much information irrelevant information Don’t settle for the default settings 28 28
  37. 37. Report Tips Use active checks, not passive reports fail the build! Use profiles if they are time consuming run them in continuous integration developers can use IDE integration Have a centralized location to deploy reports visualize problems, and errors under the build failure threshold 29 29
  38. 38. Plugin Development 30 30
  39. 39. Don’t Fear Scripting Sometimes it is easier to use a script for short, one-off, customizations antrun plugin jruby, groovy plugin, etc. If you might use it twice, consider writing a plugin 31 31
  40. 40. Plugin Development It isn’t the big deal you think it is Can 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
  41. 41. Plugin Tips Write functionality in components, with the Mojo as a “wrapper” easier to test and reuse the 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-core Minimize dependencies in general all builds have to download them! 33 33
  42. 42. Final Word Do as we say... ... but not as we do Maven 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
  43. 43. Questions? Brett Porter - brett@apache.org 35 35
  44. 44. Questions? Brett Porter - brett@apache.org 35 35
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×