Upload
brett-porter
View
10.310
Download
7
Embed Size (px)
DESCRIPTION
Second presentation on a collection of best practices given at ApacheCon US 2008
Citation preview
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