SlideShare una empresa de Scribd logo
1 de 71
Descargar para leer sin conexión
Who is this guy, anyway?
John Ferguson Smart
Consultant, Trainer, Mentor, Author, Speaker
Specialities:
 Java, Groovy/Grails
 Software Development Lifecycle
 Agile stuff (CI, TDD, BDD,...)
 Open Source
Agenda
What are we discussing today?
What makes a good build script?
Smelly build scripts
Choosing your tools
Maven tips
Ant tips
Introduction
Quality build scripts - why bother
Maintenance costs
Learning curve
Turn-over
Portability
Automation
Build quality - quality builds
What makes a good build script?
Gold Standard
Portable
Reproducible
Standard
Maintainable
Build quality - quality builds
Gold Standard
Reference build process
Reference binaries
Build quality - quality builds
Portable
Runs anywhere
Runs on any OS
No local dependencies
 Environment-specific configurations
 Specially-installed software or databases
 ...
Build quality - quality builds
Reproducible
“Play it again, Sam”
Build quality - quality builds
Standard
Knowing what to expect
Build quality - quality builds
Maintainable
Think of the next dude
Smelly builds
 So what makes a poor build script?
1) The hard coded build
2) The OS-specific build
3) The IDE-only build
4) The Magic Machine build
5) The Oral Tradition build
6) The Nested build
7) The Messy Dependencies build
8) The DYI build
9) The untrustworthy build
10) The slow build
Paths
                                                                       ..
                                                                    1/




                                                                            URLs
Smelly builds




                                                                  9.
                                                               c-
                                                             gi
                                                          lo




                                                                                               1
                                                        eb




                                                                                            00



                                                                                                           Passwords
                                                     /w




                                                                                         :7
                                                                                      om
                                                   ea




                                                                                   .c
                                               /b




                                                                                me
                                              C:




                                                                             ac
                                                                          r.
                                                                       ve
                                                                    er
                                                                 ts
                                                              es                                               .>
                                                           /t                                              "..
                                                        :/                                             ger
                                                                                                  "ti
                                                     tp                                       rd=
                The hard coded build




                                                  ht                                     swo
                                                                                   pas
                                                                            tt"
                                                                       sco
                                                                  e="
                                                            nam
                                                      ser
                                                  n u
                                              <sv
                                                                                                                            />
                                                                                                                     M E }"
                                                                                                                S_HO
                                                                                                           JBOS
                                                                                                      env.
                                                                                               = "$ {
                                                                                       alue
                                                                                s" v




                                                                                                         Environment
                                                                        jbos
                                                                 dir.
                                                          me="




                                                                                                          variables
                                                   y na
                                              pert
                                       <pro
Smelly builds
The hard coded build

<target name="checkstyle">
                                           Hard-coded directories
  <delete dir="./reports" quiet="true" />
  <mkdir dir="./reports" />
  <checkstyle config="./docs/sun_checks.xml">
    <formatter type="xml" tofile="./reports/checkstyle.xml"/>
    <fileset dir="./src" includes="**/*.java"/>
  </checkstyle>

  <style in="./reports/checkstyle.xml"
         out="./reports/checkstyle.html"
         style="checkstyle.xsl"/>

</target>
Smelly builds
    The hard coded build

    <target name="checkstyle">                Project-relative directory
<property name=”reports.checkstyle.dir”
      <delete dir="./reports" quiet="true" />
          value=”${basedir}/reports”/>
      <mkdir dir="./reports" />                         DRY
      <checkstyle config="./docs/sun_checks.xml">
<target name="checkstyle">
        <formatter type="xml" tofile="./reports/checkstyle.xml"/>
  <delete dir="${reports.checkstyle.dir}" quiet="true" />
  <mkdir<fileset dir="./src" includes="**/*.java"/>
         dir="${reports.checkstyle.dir}" />
      </checkstyle>
  <checkstyle config="./docs/sun_checks.xml">
    <formatter type="xml"
      <style in="./reports/checkstyle.xml"
                tofile="${reports.checkstyle.dir}/checkstyle.xml"/>
    <fileset out="./reports/checkstyle.html"
             dir="./src" includes="**/*.java"/>
             style="checkstyle.xsl"/>
  </checkstyle>

    </target>
  <style in="${reports.checkstyle.dir}/checkstyle.xml"
         out="${reports.checkstyle.dir}/checkstyle.html"
         style="checkstyle.xsl"/>

</target>
Smelly builds
    The hard coded build
<target name="war" >
  <war destfile="c:/tomcat/jakarta-tomcat-5.0.19/webapps/app.war"
       webxml="${src}/app.xml" basedir="${bin}" />
</target>


                  Hard-coded directories
Smelly builds
    The hard coded build
<property name="wardir"
          location="c:/tomcat/jakarta-tomcat-5.0.19/webapps"/>

<target name="war" >
  <war destfile="${wardir}" webxml="${src}/app.xml"
       basedir="${bin}" />
</target>
                  Still hard-coded
Smelly builds
   The hard coded build




<svn username="scott" password="tiger">
  <checkout url="http://subversion.acme.com/myapp/trunk"
            destPath="${subproject.dir}" />
</svn>

       Hard-coded username/password
Smelly builds
The hard coded build




 <property environment="env"/>
 <property name="dir.jboss" value="${env.JBOSS_HOME}"/>




                         Environment variable
Smelly builds
The OS-specific build


<exec command="grep "@" ${build.dir} | wc -l"
      outputproperty="token.count"/>
Smelly builds
The OS-specific build
...
CALL PAUSE.CMD
...
build.cmd

  ...
  :: Check for a non-existent IP address
  :: Note: this causes a small extra delay!
  IF NOT DEFINED NonExist SET NonExist=10.255.255.254
  PING %NonExist% -n 1 -w 100 2>NUL | FIND "TTL=" >NUL
  ...
    pause.cmd
Smelly builds
The IDE-only build
Smelly builds
The Magic Machine build



                                         Directories

                           App servers


                Databases


       Configuration files


Environment variables


Installed software or tools
Smelly builds
The Magic Machine build


 <proprerty weblogic.dir="/u01/app/bea/weblogic-9.1"/>

                                         Directories

                           App servers


                Databases


       Configuration files


Environment variables


Installed software or tools
Smelly builds
The Oral Tradition build
Smelly builds
The Nested Build

#! /bin/sh
ANT_HOME=/u01/app/tools/ant-1.7.1
...
$ANT_HOME/ant $1
project/tools/ant.sh
Smelly builds
   The Nested Build

<target name="build-subproject">
  <svn username="scott" password="tiger">
    <checkout url="http://subversion.acme.com/someproject/trunk"
              destPath="${subproject.dir}" />
  </svn>

  <ant dir="${subproject.dir}" target="build-all" />
</target>
build.xml
Smelly builds
The Messy Dependencies build
JAR files in the SCM
Unversioned JAR files
Unclear dependencies
Smelly builds
The DYI build
“Not invented here”
DYI dependencies
DYI deployments
DYI Maven releases
...
Smelly builds
The untrustworthy build
<junit fork="yes" haltonfailure="false" dir="${basedir}">
  <classpath refid="test.class.path" />
  <classpath refid="project.class.path"/>
  <formatter type="plain" usefile="true" />
  <formatter type="xml" usefile="true" />
  <batchtest fork="yes" todir="${logs.junit.dir}">
  <fileset dir="${test.unit.dir}">
    <patternset refid="test.sources.pattern"/>
  </fileset>
  </batchtest>
</junit>
Smelly builds
The slow build
Choosing your tools
Flexibility verses Convention
What’s better: flexibility or standards?
It depends what you’re doing...
Choosing your tools
                                                                  Encourage/enforce

       Standards and Conventions              Support standards
                                                                      standards


                                                                                      3
Easy to read




                                                                                      2
                              Make up your
                              own standards




               No standards
Hard to read




Ad-hoc scripting                                      Standards and Conventions
Choosing your tools
         Flexibility and expressiveness
                                          3                      Do whatever you
  Easy to read



                                                                      want


                         2
                 Encourage/enforce
                     standards
  Hard to read




Makes you stick to conventions                Easy to do whatever you want
Choosing your tools
Flexibility verses Convention
Build Scripting Rule 1
    “A build script will tend to reflect the personality of
                        it’s developer”
Choosing your tools
Flexibility verses Convention
Build Scripting Rule 2
     “The more flexible a build script, the more likely it
             is to become unmaintainable”
Choosing your tools
Flexibility verses Convention
Flexibility is great for some jobs:
 Ad-hoc tasks
 Some deployment tasks
 “Out-of-the-box” stuff
Choosing your tools
Flexibility verses Convention
But too much flexibility is hard to maintain
Ant tips
Better Ant scripts
Consistent conventions
Declare your dependencies
Make it readable
Tidy up your mess
Avoid long scripts
Ant tips
Be consistent
Standardize target names
Document your public targets
Ant tips
Declare your dependencies
Use an Enterprise Repository Manager
Several tool choices:
 Maven Ant Tasks
 Ivy
Ant tips
 Using the Maven Ant Tasks
  Declare dependencies
  Deploy to a Maven Enterprise Repository
<artifact:dependencies pathId="dependency.classpath">
  <dependency groupId="junit" artifactId="junit"
              version="3.8.2" scope="test"/>
  <dependency groupId="javax.servlet" artifactId="servlet-api"
              version="2.4" scope="provided"/>
</artifact:dependencies>
Ant tips
Make it readable
 Write a build script like your source code...
 Avoid long targets
 Avoid long build scripts
 Use descriptive target names
Ant tips
Tidy up your mess
Always define a ‘clean’ target.
Ant tips
Move to Maven ;-)
Maven tips
Better Maven scripts
Simple
Portable
Reproducible
Clean
Automated
Maven tips
Keep it simple
Use modules
Use an organization-level POM
Maven tips
Keep it portable
No hard-coding
Define sensible defaults for properties and profiles
Avoid resource filtering for production code
Maven tips
Keep it reproducible
Avoid external snapshots
Specify plugin versions
Use consistent environments
Maven tips
Consistent environments
Enforcing a minimum Maven version
 <?xml version="1.0"?>
 <project...>
 	 <modelVersion>4.0.0</modelVersion>
 	 <groupId>com.ciwithhudson.gameoflife</groupId>
 	 <artifactId>gameoflife</artifactId>
 	 <version>0.0.1-SNAPSHOT</version>
                                       Minimum Maven version
 	 <name>gameoflife</name>
 	 <prerequisites>
 	 	 <maven>2.2.1</maven>
 	 </prerequisites>
Maven tips
Consistent environments
Use the same version of Maven
Use a “standard” Maven installation across the organization
 Use a global settings.xml file
 Store a copy in SCM
 Enforce a minimum Maven version in your projects
Maven tips
Enforcing consistency with the enforcer plugin
Maven version
JDK version
Snapshots
Plugin versions
OS
...
Maven tips
Enforce the Maven version
     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.0-beta-1</version>
        <executions>
          <execution>
            <id>enforce-maven-version</id>
            <goals>
              <goal>enforce</goal>
            </goals>                      Minimum Maven version
            <configuration>
              <rules>
                <requireMavenVersion>
                  <version>2.2.1</version>
                </requireMavenVersion>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
Maven tips
Enforce the JDK version
All developers should be using the same JDKs
 Incompatible bytecode
 Different XML parsers
 Different Maven behaviour
Maven tips
Enforce the JDK version
     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.0-beta-1</version>
        <executions>
          <execution>
            <id>enforce-jdk-version</id>
            <goals>
              <goal>enforce</goal>
            </goals>                      Authorized JDK versions
            <configuration>
              <rules>
                <requireJavaVersion>
                  <version>[1.5.0,1.6.0)</version>
                </requireJavaVersion>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
Maven tips
Specify your plugin versions
Undeclared version numbers are bad
 Inconsistent builds across different machines
 Non-repeatable builds
 Plugin changes can break the build
 Don’t use SNAPSHOT plugins either
Maven tips
Specify your plugin versions
     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-enforcer-plugin</artifactId>
        <version>1.0-beta-1</version>
        <executions>
          <execution>
            <id>enforce-versions</id>
            <goals>
              <goal>enforce</goal>
            </goals>               Plugin versions must be defined
            <configuration>
              <rules>
                <requirePluginVersions/>
              </rules>
            </configuration>
          </execution>
        </executions>
      </plugin>
Maven tips
Keep it clean
Keep tabs on your dependencies:
 What dependencies are you actually using?
 What dependencies do you really need?
Maven tips
Dependency list
What dependencies are you actually using?
 $ mvn dependency:list
 [INFO] Scanning for projects...        mvn dependency:list
 [INFO] Searching repository for plugin with prefix: 'dependency'.
 [INFO] ------------------------------------------------------------------------
 [INFO] Building babble-core
 [INFO]    task-segment: [dependency:list]
 [INFO] ------------------------------------------------------------------------
 [INFO] [dependency:list]
 [INFO]
 [INFO] The following files have been resolved:
 [INFO]    antlr:antlr:jar:2.7.6:compile
 ...
 [INFO]    commons-collections:commons-collections:jar:2.1.1:compile
 [INFO]    commons-logging:commons-logging:jar:1.0.4:compile
 [INFO]    dom4j:dom4j:jar:1.6.1:compile
 [INFO]    javax.persistence:persistence-api:jar:1.0:compile
 [INFO]    javax.transaction:jta:jar:1.0.1B:compile
 [INFO]    junit:junit:jar:4.5:test
 [INFO]    net.sf.ehcache:ehcache:jar:1.2:compile
 [INFO]    org.hamcrest:hamcrest-all:jar:1.1:compile
 [INFO]    org.hibernate:hibernate:jar:3.2.0.ga:compile
 [INFO]    org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
 [INFO]
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESSFUL
 [INFO] ------------------------------------------------------------------------
Maven tips
Dependency tree
Where do they come from?
 $ mvn dependency:tree
 [INFO] Scanning for projects...       mvn dependency:tree
 [INFO] Searching repository for plugin with prefix: 'dependency'.
 [INFO] ------------------------------------------------------------------------
 [INFO] Building babble-core
 [INFO]    task-segment: [dependency:tree]
 [INFO] ------------------------------------------------------------------------
 [INFO] [dependency:tree]
 [INFO] com.sonatype.training:babble-core:jar:1.0-SNAPSHOT
 [INFO] +- org.hibernate:hibernate:jar:3.2.0.ga:compile
 [INFO] | +- net.sf.ehcache:ehcache:jar:1.2:compile
 [INFO] | +- javax.transaction:jta:jar:1.0.1B:compile
 [INFO] | +- commons-logging:commons-logging:jar:1.0.4:compile
 [INFO] | +- asm:asm-attrs:jar:1.5.3:compile
 [INFO] | +- dom4j:dom4j:jar:1.6.1:compile
 [INFO] | +- antlr:antlr:jar:2.7.6:compile
 [INFO] | +- cglib:cglib:jar:2.1_3:compile
 [INFO] | +- asm:asm:jar:1.5.3:compile
 [INFO] | - commons-collections:commons-collections:jar:2.1.1:compile
 [INFO] +- org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
 [INFO] | - javax.persistence:persistence-api:jar:1.0:compile
 [INFO] +- junit:junit:jar:4.5:test
 [INFO] - org.hamcrest:hamcrest-all:jar:1.1:compile
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESSFUL
 [INFO] ------------------------------------------------------------------------
Maven tips
Dependencies in Eclipse
Eclipse has an equivalent screen
Maven tips
Dependency analyse
What dependencies do you really need?
 $ mvn dependency:analyze
 [INFO] Scanning for projects...     mvn dependency:analyse
 [INFO] Searching repository for plugin with prefix: 'dependency'.
 [INFO] ------------------------------------------------------------------------
 [INFO] Building babble-core
 [INFO]    task-segment: [dependency:analyze]
 [INFO] ------------------------------------------------------------------------
 [INFO] Preparing dependency:analyze
 ...                                                  Used but not declared
 [INFO] [dependency:analyze]
 [WARNING] Used undeclared dependencies found:
 [WARNING]    javax.persistence:persistence-api:jar:1.0:compile
 [WARNING] Unused declared dependencies found:
 [WARNING]    org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile
 [WARNING]    org.hibernate:hibernate:jar:3.2.0.ga:compile
 [INFO] ------------------------------------------------------------------------
 [INFO] BUILD SUCCESSFUL
                                                       Declared but not used
 [INFO] ------------------------------------------------------------------------
Maven tips
Excluding dependencies
What if you don’t want a dependency?
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring</artifactId>
                                             Don’t include JMS
      <version>2.5.5</version>
      <exclusions>
       <exclusion>
        <groupId>javax.jms</groupId>
        <artifactId>jms<artifactId>
      </exclusion>
     </exclusions>
    </dependency>
    <dependency>
      <groupId>org.apache.geronimo.specs</groupId>
      <artifactId>geronimo-jms_1.1_spec</artifact>
      <version>1.1</version>
    </dependency>
 <dependencies>
Maven tips
  Standardizing versions
    Use dependencyManagement for consistency

<dependencyManagement>                       Parent pom
  <dependencies>
    <dependency>
    ! <groupId>mysql</groupId>
  ! <artifactId>mysql-connector-java</artifactId>
   ! <version>5.1.6</version>
    </dependency>
    <dependency>
    ! <groupId>postgres</groupId>
  ! <artifactId>postgres</artifactId>
   ! <version>7.3.2</version>
        <dependencies>                                  Child pom
    </dependency>
          <dependency>
  </dependencies>
           !<groupId>mysql</groupId>
</dependencyManagement>
             <artifactId>mysql-connector-java</artifactId>
          </dependency>
        </dependencies>
Maven tips
Keep it automated
Plan your release strategy
Use a Repository Manager
Automatic snapshot deployments
Automated releases
Maven tips
Maven best practices for CI builds
Use batch mode (-B)
Always check or snapshot updates (-U)
Use a repository per project
Print test failures to stdout (-Dsurefire.useFile=false)
Maven tips
Know when to script it
Groovy or Ant scripting is easy in Maven
Call external scripts when appropriate
Maven tips
Know when to script it
It’s pretty easy in Maven 2...
 <project>
    <build>
       <plugins>
         <plugin>
           <groupId>org.codehaus.groovy.maven</groupId>
           <artifactId>gmaven-plugin</artifactId>
           <version>1.0-rc-5</version>
           <executions>
              <execution>
                 <phase>compile</phase>
                 <goals>
                   <goal>execute</goal>
                 </goals>
                 <configuration>
                    <source>
                      println "Hi there I’m compiling ${project.name}"
                    </source>
                 </configuration>
               </execution>
           </executions>
         </plugin>
       </plugins>
     </build>
     ...
Maven tips
Know when to script it
It’s even easier in Maven 3...
 project {
   build {
      $execute(id: 'compilation-script', phase: 'compile') {
        println "Hi there I’m compiling ${project.name}"
      }
      $execute(id: 'validation-script', phase: 'validate') {
        println "Hi there I’m validating ${project.name}"
      }
      ...
   }
 }
Java Power Tools Bootcamp
London - October 13-17 2010
Zen and-the-art-of-build-script-maintenance-skillsmatter

Más contenido relacionado

Destacado

Apache ant
Apache antApache ant
Apache ant
koniik
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011
Ching Yi Chan
 
Erlang vs. Java
Erlang vs. JavaErlang vs. Java
Erlang vs. Java
Artan Cami
 

Destacado (20)

Ant_quick_guide
Ant_quick_guideAnt_quick_guide
Ant_quick_guide
 
Jvm a brief introduction
Jvm  a brief introductionJvm  a brief introduction
Jvm a brief introduction
 
Java Build Tools
Java Build ToolsJava Build Tools
Java Build Tools
 
Architecting your Frontend
Architecting your FrontendArchitecting your Frontend
Architecting your Frontend
 
Gradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhereGradle 2.Write once, builde everywhere
Gradle 2.Write once, builde everywhere
 
Angular.js
Angular.jsAngular.js
Angular.js
 
Make Your Builds More Groovy
Make Your Builds More GroovyMake Your Builds More Groovy
Make Your Builds More Groovy
 
Apache maven 2 overview
Apache maven 2 overviewApache maven 2 overview
Apache maven 2 overview
 
4장. Class Loader
4장. Class Loader4장. Class Loader
4장. Class Loader
 
Tutorial to develop build files using ANT
Tutorial to develop build files using ANTTutorial to develop build files using ANT
Tutorial to develop build files using ANT
 
Apache maven 2 overview
Apache maven 2 overviewApache maven 2 overview
Apache maven 2 overview
 
Apache ant
Apache antApache ant
Apache ant
 
Java Classloaders
Java ClassloadersJava Classloaders
Java Classloaders
 
Java Build Tool course in 2011
Java Build Tool course in 2011Java Build Tool course in 2011
Java Build Tool course in 2011
 
Apache Ant
Apache AntApache Ant
Apache Ant
 
Automated Frontend Testing
Automated Frontend TestingAutomated Frontend Testing
Automated Frontend Testing
 
Front-End Testing: Demystified
Front-End Testing: DemystifiedFront-End Testing: Demystified
Front-End Testing: Demystified
 
Apache Ant
Apache AntApache Ant
Apache Ant
 
Erlang vs. Java
Erlang vs. JavaErlang vs. Java
Erlang vs. Java
 
Manen Ant SVN
Manen Ant SVNManen Ant SVN
Manen Ant SVN
 

Similar a Zen and-the-art-of-build-script-maintenance-skillsmatter

Eduserv OpenID Meeting: OpenID Today
Eduserv OpenID Meeting: OpenID TodayEduserv OpenID Meeting: OpenID Today
Eduserv OpenID Meeting: OpenID Today
David Recordon
 
Apache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and RESTApache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and REST
Carsten Ziegeler
 
Mirage: extreme specialisation of virtual appliances
Mirage: extreme specialisation of virtual appliancesMirage: extreme specialisation of virtual appliances
Mirage: extreme specialisation of virtual appliances
The Linux Foundation
 
H sgp keynot
H sgp keynotH sgp keynot
H sgp keynot
114970
 
Airlines 2.0 - How airlines can use Web 2.0 for branding
Airlines 2.0 - How airlines can use Web 2.0 for brandingAirlines 2.0 - How airlines can use Web 2.0 for branding
Airlines 2.0 - How airlines can use Web 2.0 for branding
SimpliFlying
 
Approaching Rich Internet Applications
Approaching Rich Internet ApplicationsApproaching Rich Internet Applications
Approaching Rich Internet Applications
Dhaval Dalal
 
Open stack - Presenation by Thierry Carrez
Open stack - Presenation by Thierry CarrezOpen stack - Presenation by Thierry Carrez
Open stack - Presenation by Thierry Carrez
eNovance
 
Starter day presentation art of the bootstrap
Starter day presentation   art of the bootstrapStarter day presentation   art of the bootstrap
Starter day presentation art of the bootstrap
Scott Farquhar
 

Similar a Zen and-the-art-of-build-script-maintenance-skillsmatter (20)

Zen and-the-art-of-build-script-maintenance
Zen and-the-art-of-build-script-maintenanceZen and-the-art-of-build-script-maintenance
Zen and-the-art-of-build-script-maintenance
 
The Future OS
The Future OS The Future OS
The Future OS
 
An Introduction To FluidDB - a social database in the cloud
An Introduction To FluidDB - a social database in the cloudAn Introduction To FluidDB - a social database in the cloud
An Introduction To FluidDB - a social database in the cloud
 
An Introduction to FluidDB
An Introduction to FluidDBAn Introduction to FluidDB
An Introduction to FluidDB
 
Hacker Lab Summary
Hacker Lab SummaryHacker Lab Summary
Hacker Lab Summary
 
Hacker Lab Startup Community Hackerspace
Hacker Lab Startup Community HackerspaceHacker Lab Startup Community Hackerspace
Hacker Lab Startup Community Hackerspace
 
Eduserv OpenID Meeting: OpenID Today
Eduserv OpenID Meeting: OpenID TodayEduserv OpenID Meeting: OpenID Today
Eduserv OpenID Meeting: OpenID Today
 
The 21st Century Mapping Agency
The 21st Century Mapping AgencyThe 21st Century Mapping Agency
The 21st Century Mapping Agency
 
Apache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and RESTApache Sling : JCR, OSGi, Scripting and REST
Apache Sling : JCR, OSGi, Scripting and REST
 
Mirage: extreme specialisation of virtual appliances
Mirage: extreme specialisation of virtual appliancesMirage: extreme specialisation of virtual appliances
Mirage: extreme specialisation of virtual appliances
 
Drupal Optimization
Drupal OptimizationDrupal Optimization
Drupal Optimization
 
Xero Advertisment - NZ Accountants Journal November 2007
Xero Advertisment - NZ Accountants Journal  November 2007Xero Advertisment - NZ Accountants Journal  November 2007
Xero Advertisment - NZ Accountants Journal November 2007
 
Web 2.0 Expo Berlin: OpenID Emerging from Web 2.0
Web 2.0 Expo Berlin: OpenID Emerging from Web 2.0Web 2.0 Expo Berlin: OpenID Emerging from Web 2.0
Web 2.0 Expo Berlin: OpenID Emerging from Web 2.0
 
Plant hormone and responses
Plant hormone and responsesPlant hormone and responses
Plant hormone and responses
 
H sgp keynot
H sgp keynotH sgp keynot
H sgp keynot
 
Airlines 2.0 - How airlines can use Web 2.0 for branding
Airlines 2.0 - How airlines can use Web 2.0 for brandingAirlines 2.0 - How airlines can use Web 2.0 for branding
Airlines 2.0 - How airlines can use Web 2.0 for branding
 
Approaching Rich Internet Applications
Approaching Rich Internet ApplicationsApproaching Rich Internet Applications
Approaching Rich Internet Applications
 
OpenID Foundation Japan Chapter Announcement
OpenID Foundation Japan Chapter AnnouncementOpenID Foundation Japan Chapter Announcement
OpenID Foundation Japan Chapter Announcement
 
Open stack - Presenation by Thierry Carrez
Open stack - Presenation by Thierry CarrezOpen stack - Presenation by Thierry Carrez
Open stack - Presenation by Thierry Carrez
 
Starter day presentation art of the bootstrap
Starter day presentation   art of the bootstrapStarter day presentation   art of the bootstrap
Starter day presentation art of the bootstrap
 

Más de Skills Matter

Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
Skills Matter
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
Skills Matter
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
Skills Matter
 

Más de Skills Matter (20)

5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence5 things cucumber is bad at by Richard Lawrence
5 things cucumber is bad at by Richard Lawrence
 
Patterns for slick database applications
Patterns for slick database applicationsPatterns for slick database applications
Patterns for slick database applications
 
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvmScala e xchange 2013 haoyi li on metascala a tiny diy jvm
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
 
Oscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheimOscar reiken jr on our success at manheim
Oscar reiken jr on our success at manheim
 
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
 
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberlCukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc ian dees on elixir, erlang, and cucumberl
 
Cukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.jsCukeup nyc peter bell on getting started with cucumber.js
Cukeup nyc peter bell on getting started with cucumber.js
 
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
 
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
 
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source worldProgressive f# tutorials nyc don syme on keynote f# in the open source world
Progressive f# tutorials nyc don syme on keynote f# in the open source world
 
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
 
Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#Dmitry mozorov on code quotations code as-data for f#
Dmitry mozorov on code quotations code as-data for f#
 
A poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testingA poet's guide_to_acceptance_testing
A poet's guide_to_acceptance_testing
 
Russ miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-diveRuss miles-cloudfoundry-deep-dive
Russ miles-cloudfoundry-deep-dive
 
Serendipity-neo4j
Serendipity-neo4jSerendipity-neo4j
Serendipity-neo4j
 
Simon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelismSimon Peyton Jones: Managing parallelism
Simon Peyton Jones: Managing parallelism
 
Plug 20110217
Plug   20110217Plug   20110217
Plug 20110217
 
Lug presentation
Lug presentationLug presentation
Lug presentation
 
I went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_tI went to_a_communications_workshop_and_they_t
I went to_a_communications_workshop_and_they_t
 
Plug saiku
Plug   saikuPlug   saiku
Plug saiku
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 

Zen and-the-art-of-build-script-maintenance-skillsmatter

  • 1.
  • 2.
  • 3. Who is this guy, anyway? John Ferguson Smart Consultant, Trainer, Mentor, Author, Speaker Specialities: Java, Groovy/Grails Software Development Lifecycle Agile stuff (CI, TDD, BDD,...) Open Source
  • 4. Agenda What are we discussing today? What makes a good build script? Smelly build scripts Choosing your tools Maven tips Ant tips
  • 5. Introduction Quality build scripts - why bother Maintenance costs Learning curve Turn-over Portability Automation
  • 6. Build quality - quality builds What makes a good build script? Gold Standard Portable Reproducible Standard Maintainable
  • 7. Build quality - quality builds Gold Standard Reference build process Reference binaries
  • 8. Build quality - quality builds Portable Runs anywhere Runs on any OS No local dependencies Environment-specific configurations Specially-installed software or databases ...
  • 9. Build quality - quality builds Reproducible “Play it again, Sam”
  • 10. Build quality - quality builds Standard Knowing what to expect
  • 11. Build quality - quality builds Maintainable Think of the next dude
  • 12. Smelly builds So what makes a poor build script? 1) The hard coded build 2) The OS-specific build 3) The IDE-only build 4) The Magic Machine build 5) The Oral Tradition build 6) The Nested build 7) The Messy Dependencies build 8) The DYI build 9) The untrustworthy build 10) The slow build
  • 13. Paths .. 1/ URLs Smelly builds 9. c- gi lo 1 eb 00 Passwords /w :7 om ea .c /b me C: ac r. ve er ts es .> /t ".. :/ ger "ti tp rd= The hard coded build ht swo pas tt" sco e=" nam ser n u <sv /> M E }" S_HO JBOS env. = "$ { alue s" v Environment jbos dir. me=" variables y na pert <pro
  • 14. Smelly builds The hard coded build <target name="checkstyle"> Hard-coded directories <delete dir="./reports" quiet="true" /> <mkdir dir="./reports" /> <checkstyle config="./docs/sun_checks.xml"> <formatter type="xml" tofile="./reports/checkstyle.xml"/> <fileset dir="./src" includes="**/*.java"/> </checkstyle> <style in="./reports/checkstyle.xml" out="./reports/checkstyle.html" style="checkstyle.xsl"/> </target>
  • 15. Smelly builds The hard coded build <target name="checkstyle"> Project-relative directory <property name=”reports.checkstyle.dir” <delete dir="./reports" quiet="true" /> value=”${basedir}/reports”/> <mkdir dir="./reports" /> DRY <checkstyle config="./docs/sun_checks.xml"> <target name="checkstyle"> <formatter type="xml" tofile="./reports/checkstyle.xml"/> <delete dir="${reports.checkstyle.dir}" quiet="true" /> <mkdir<fileset dir="./src" includes="**/*.java"/> dir="${reports.checkstyle.dir}" /> </checkstyle> <checkstyle config="./docs/sun_checks.xml"> <formatter type="xml" <style in="./reports/checkstyle.xml" tofile="${reports.checkstyle.dir}/checkstyle.xml"/> <fileset out="./reports/checkstyle.html" dir="./src" includes="**/*.java"/> style="checkstyle.xsl"/> </checkstyle> </target> <style in="${reports.checkstyle.dir}/checkstyle.xml" out="${reports.checkstyle.dir}/checkstyle.html" style="checkstyle.xsl"/> </target>
  • 16. Smelly builds The hard coded build <target name="war" > <war destfile="c:/tomcat/jakarta-tomcat-5.0.19/webapps/app.war" webxml="${src}/app.xml" basedir="${bin}" /> </target> Hard-coded directories
  • 17. Smelly builds The hard coded build <property name="wardir" location="c:/tomcat/jakarta-tomcat-5.0.19/webapps"/> <target name="war" > <war destfile="${wardir}" webxml="${src}/app.xml" basedir="${bin}" /> </target> Still hard-coded
  • 18. Smelly builds The hard coded build <svn username="scott" password="tiger"> <checkout url="http://subversion.acme.com/myapp/trunk" destPath="${subproject.dir}" /> </svn> Hard-coded username/password
  • 19. Smelly builds The hard coded build <property environment="env"/> <property name="dir.jboss" value="${env.JBOSS_HOME}"/> Environment variable
  • 20. Smelly builds The OS-specific build <exec command="grep "@" ${build.dir} | wc -l" outputproperty="token.count"/>
  • 21. Smelly builds The OS-specific build ... CALL PAUSE.CMD ... build.cmd ... :: Check for a non-existent IP address :: Note: this causes a small extra delay! IF NOT DEFINED NonExist SET NonExist=10.255.255.254 PING %NonExist% -n 1 -w 100 2>NUL | FIND "TTL=" >NUL ... pause.cmd
  • 23. Smelly builds The Magic Machine build Directories App servers Databases Configuration files Environment variables Installed software or tools
  • 24. Smelly builds The Magic Machine build <proprerty weblogic.dir="/u01/app/bea/weblogic-9.1"/> Directories App servers Databases Configuration files Environment variables Installed software or tools
  • 25. Smelly builds The Oral Tradition build
  • 26. Smelly builds The Nested Build #! /bin/sh ANT_HOME=/u01/app/tools/ant-1.7.1 ... $ANT_HOME/ant $1 project/tools/ant.sh
  • 27. Smelly builds The Nested Build <target name="build-subproject"> <svn username="scott" password="tiger"> <checkout url="http://subversion.acme.com/someproject/trunk" destPath="${subproject.dir}" /> </svn> <ant dir="${subproject.dir}" target="build-all" /> </target> build.xml
  • 28. Smelly builds The Messy Dependencies build JAR files in the SCM Unversioned JAR files Unclear dependencies
  • 29. Smelly builds The DYI build “Not invented here” DYI dependencies DYI deployments DYI Maven releases ...
  • 30. Smelly builds The untrustworthy build <junit fork="yes" haltonfailure="false" dir="${basedir}"> <classpath refid="test.class.path" /> <classpath refid="project.class.path"/> <formatter type="plain" usefile="true" /> <formatter type="xml" usefile="true" /> <batchtest fork="yes" todir="${logs.junit.dir}"> <fileset dir="${test.unit.dir}"> <patternset refid="test.sources.pattern"/> </fileset> </batchtest> </junit>
  • 32. Choosing your tools Flexibility verses Convention What’s better: flexibility or standards? It depends what you’re doing...
  • 33. Choosing your tools Encourage/enforce Standards and Conventions Support standards standards 3 Easy to read 2 Make up your own standards No standards Hard to read Ad-hoc scripting Standards and Conventions
  • 34. Choosing your tools Flexibility and expressiveness 3 Do whatever you Easy to read want 2 Encourage/enforce standards Hard to read Makes you stick to conventions Easy to do whatever you want
  • 35. Choosing your tools Flexibility verses Convention Build Scripting Rule 1 “A build script will tend to reflect the personality of it’s developer”
  • 36. Choosing your tools Flexibility verses Convention Build Scripting Rule 2 “The more flexible a build script, the more likely it is to become unmaintainable”
  • 37. Choosing your tools Flexibility verses Convention Flexibility is great for some jobs: Ad-hoc tasks Some deployment tasks “Out-of-the-box” stuff
  • 38. Choosing your tools Flexibility verses Convention But too much flexibility is hard to maintain
  • 39. Ant tips Better Ant scripts Consistent conventions Declare your dependencies Make it readable Tidy up your mess Avoid long scripts
  • 40. Ant tips Be consistent Standardize target names Document your public targets
  • 41. Ant tips Declare your dependencies Use an Enterprise Repository Manager Several tool choices: Maven Ant Tasks Ivy
  • 42. Ant tips Using the Maven Ant Tasks Declare dependencies Deploy to a Maven Enterprise Repository <artifact:dependencies pathId="dependency.classpath"> <dependency groupId="junit" artifactId="junit" version="3.8.2" scope="test"/> <dependency groupId="javax.servlet" artifactId="servlet-api" version="2.4" scope="provided"/> </artifact:dependencies>
  • 43. Ant tips Make it readable Write a build script like your source code... Avoid long targets Avoid long build scripts Use descriptive target names
  • 44. Ant tips Tidy up your mess Always define a ‘clean’ target.
  • 45. Ant tips Move to Maven ;-)
  • 46. Maven tips Better Maven scripts Simple Portable Reproducible Clean Automated
  • 47. Maven tips Keep it simple Use modules Use an organization-level POM
  • 48. Maven tips Keep it portable No hard-coding Define sensible defaults for properties and profiles Avoid resource filtering for production code
  • 49. Maven tips Keep it reproducible Avoid external snapshots Specify plugin versions Use consistent environments
  • 50. Maven tips Consistent environments Enforcing a minimum Maven version <?xml version="1.0"?> <project...> <modelVersion>4.0.0</modelVersion> <groupId>com.ciwithhudson.gameoflife</groupId> <artifactId>gameoflife</artifactId> <version>0.0.1-SNAPSHOT</version> Minimum Maven version <name>gameoflife</name> <prerequisites> <maven>2.2.1</maven> </prerequisites>
  • 51. Maven tips Consistent environments Use the same version of Maven Use a “standard” Maven installation across the organization Use a global settings.xml file Store a copy in SCM Enforce a minimum Maven version in your projects
  • 52. Maven tips Enforcing consistency with the enforcer plugin Maven version JDK version Snapshots Plugin versions OS ...
  • 53. Maven tips Enforce the Maven version <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-maven-version</id> <goals> <goal>enforce</goal> </goals> Minimum Maven version <configuration> <rules> <requireMavenVersion> <version>2.2.1</version> </requireMavenVersion> </rules> </configuration> </execution> </executions> </plugin>
  • 54. Maven tips Enforce the JDK version All developers should be using the same JDKs Incompatible bytecode Different XML parsers Different Maven behaviour
  • 55. Maven tips Enforce the JDK version <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-jdk-version</id> <goals> <goal>enforce</goal> </goals> Authorized JDK versions <configuration> <rules> <requireJavaVersion> <version>[1.5.0,1.6.0)</version> </requireJavaVersion> </rules> </configuration> </execution> </executions> </plugin>
  • 56. Maven tips Specify your plugin versions Undeclared version numbers are bad Inconsistent builds across different machines Non-repeatable builds Plugin changes can break the build Don’t use SNAPSHOT plugins either
  • 57. Maven tips Specify your plugin versions <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>1.0-beta-1</version> <executions> <execution> <id>enforce-versions</id> <goals> <goal>enforce</goal> </goals> Plugin versions must be defined <configuration> <rules> <requirePluginVersions/> </rules> </configuration> </execution> </executions> </plugin>
  • 58. Maven tips Keep it clean Keep tabs on your dependencies: What dependencies are you actually using? What dependencies do you really need?
  • 59. Maven tips Dependency list What dependencies are you actually using? $ mvn dependency:list [INFO] Scanning for projects... mvn dependency:list [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:list] [INFO] ------------------------------------------------------------------------ [INFO] [dependency:list] [INFO] [INFO] The following files have been resolved: [INFO] antlr:antlr:jar:2.7.6:compile ... [INFO] commons-collections:commons-collections:jar:2.1.1:compile [INFO] commons-logging:commons-logging:jar:1.0.4:compile [INFO] dom4j:dom4j:jar:1.6.1:compile [INFO] javax.persistence:persistence-api:jar:1.0:compile [INFO] javax.transaction:jta:jar:1.0.1B:compile [INFO] junit:junit:jar:4.5:test [INFO] net.sf.ehcache:ehcache:jar:1.2:compile [INFO] org.hamcrest:hamcrest-all:jar:1.1:compile [INFO] org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [INFO] [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
  • 60. Maven tips Dependency tree Where do they come from? $ mvn dependency:tree [INFO] Scanning for projects... mvn dependency:tree [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:tree] [INFO] ------------------------------------------------------------------------ [INFO] [dependency:tree] [INFO] com.sonatype.training:babble-core:jar:1.0-SNAPSHOT [INFO] +- org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] | +- net.sf.ehcache:ehcache:jar:1.2:compile [INFO] | +- javax.transaction:jta:jar:1.0.1B:compile [INFO] | +- commons-logging:commons-logging:jar:1.0.4:compile [INFO] | +- asm:asm-attrs:jar:1.5.3:compile [INFO] | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | +- antlr:antlr:jar:2.7.6:compile [INFO] | +- cglib:cglib:jar:2.1_3:compile [INFO] | +- asm:asm:jar:1.5.3:compile [INFO] | - commons-collections:commons-collections:jar:2.1.1:compile [INFO] +- org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [INFO] | - javax.persistence:persistence-api:jar:1.0:compile [INFO] +- junit:junit:jar:4.5:test [INFO] - org.hamcrest:hamcrest-all:jar:1.1:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
  • 61. Maven tips Dependencies in Eclipse Eclipse has an equivalent screen
  • 62. Maven tips Dependency analyse What dependencies do you really need? $ mvn dependency:analyze [INFO] Scanning for projects... mvn dependency:analyse [INFO] Searching repository for plugin with prefix: 'dependency'. [INFO] ------------------------------------------------------------------------ [INFO] Building babble-core [INFO] task-segment: [dependency:analyze] [INFO] ------------------------------------------------------------------------ [INFO] Preparing dependency:analyze ... Used but not declared [INFO] [dependency:analyze] [WARNING] Used undeclared dependencies found: [WARNING] javax.persistence:persistence-api:jar:1.0:compile [WARNING] Unused declared dependencies found: [WARNING] org.hibernate:hibernate-annotations:jar:3.2.0.ga:compile [WARNING] org.hibernate:hibernate:jar:3.2.0.ga:compile [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL Declared but not used [INFO] ------------------------------------------------------------------------
  • 63. Maven tips Excluding dependencies What if you don’t want a dependency? <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> Don’t include JMS <version>2.5.5</version> <exclusions> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms<artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jms_1.1_spec</artifact> <version>1.1</version> </dependency> <dependencies>
  • 64. Maven tips Standardizing versions Use dependencyManagement for consistency <dependencyManagement> Parent pom <dependencies> <dependency> ! <groupId>mysql</groupId> ! <artifactId>mysql-connector-java</artifactId> ! <version>5.1.6</version> </dependency> <dependency> ! <groupId>postgres</groupId> ! <artifactId>postgres</artifactId> ! <version>7.3.2</version> <dependencies> Child pom </dependency> <dependency> </dependencies> !<groupId>mysql</groupId> </dependencyManagement> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies>
  • 65. Maven tips Keep it automated Plan your release strategy Use a Repository Manager Automatic snapshot deployments Automated releases
  • 66. Maven tips Maven best practices for CI builds Use batch mode (-B) Always check or snapshot updates (-U) Use a repository per project Print test failures to stdout (-Dsurefire.useFile=false)
  • 67. Maven tips Know when to script it Groovy or Ant scripting is easy in Maven Call external scripts when appropriate
  • 68. Maven tips Know when to script it It’s pretty easy in Maven 2... <project> <build> <plugins> <plugin> <groupId>org.codehaus.groovy.maven</groupId> <artifactId>gmaven-plugin</artifactId> <version>1.0-rc-5</version> <executions> <execution> <phase>compile</phase> <goals> <goal>execute</goal> </goals> <configuration> <source> println "Hi there I’m compiling ${project.name}" </source> </configuration> </execution> </executions> </plugin> </plugins> </build> ...
  • 69. Maven tips Know when to script it It’s even easier in Maven 3... project { build { $execute(id: 'compilation-script', phase: 'compile') { println "Hi there I’m compiling ${project.name}" } $execute(id: 'validation-script', phase: 'validate') { println "Hi there I’m validating ${project.name}" } ... } }
  • 70. Java Power Tools Bootcamp London - October 13-17 2010