Build Lifecycle Craftsmanship for the Transylvania JUG

Preview:

Citation preview

Build Lifecycle Craftsmanship

at the Transylvania JUG

by Matthew McCullough

Matthew McCullough

@matthewmccull

➡Gradle ➡Jenkins

➡Sonar➡Maven 3

➡VisualVM

➡BTrace

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

Probablythe most important technical bookof 2010

-Martin Fowler, ThoughtWorks

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡Maven 3

http://maven.apache.org/

➡Why not stay with it?➡What’s new?

Maven 2.x?

➡Performance➡Memory footprint➡Parallelism

Maven 3.x

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡Gradle

http://gradle.org/

➡Groovy DSL➡Customizable lifecycle➡Suitable for build masters and users

Better Build Tool

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡Jenkins

http://jenkins-ci.org/

it all started with...

and now the space is crowded...

Software tools for continuous integration include:■AnthillPro — continuous integration server by Urbancode■Apache Continuum — continuous integration server

supporting Apache Maven and Apache Ant. Supports CVS, Subversion, Ant, Maven, and shell scripts■Apache Gump — continuous integration tool by Apache■Automated Build Studio — proprietary automated build,

continuous integration and release management system by AutomatedQA■Bamboo — proprietary continuous integration server by

Atlassian Software Systems■BuildBot — Python/Twisted-based continuous build

system■BuildMaster — proprietary application lifecycle

management and continuous integration tool by Inedo■CABIE - Continuous Automated Build and Integration

Environment — open source, written in Perl; works with CVS, Subversion, AccuRev, Bazaar and Perforce■Cascade — proprietary continuous integration tool;

provides a checkpointing facility to build and test changes before they are committed■codeBeamer — proprietary collaboration software with

built-in continuous integration features■CruiseControl — Java-based framework for a continuous

build process■CruiseControl.NET — .NET-based automated continuous

integration server■CruiseControl.rb - Lightweight, Ruby-based continuous

integration server that can build any codebase, not only Ruby, released under Apache Licence 2.0■ElectricCommander — proprietary continuous integration

and release management solution from Electric Cloud■FinalBuilder Server — proprietary automated build and

continuous integration server by VSoft Technologies■Go — proprietary agile build and release management

software by Thoughtworks■Jenkins (formerly known as Hudson) — MIT-licensed,

written in Java, runs in servlet container, supports CVS, Subversion, Mercurial, Git, StarTeam, Clearcase, Ant, NAnt, Maven, and shell scripts■Software Configuration and Library Manager — software

configuration management system for z/OS by IBM Rational Software■QuickBuild - proprietary continuous integration server

with free community edition featuring build life cycle management and pre-commit verification.■TeamCity — proprietary continuous-integration server by

JetBrains with free professional edition■Team Foundation Server — proprietary continuous

integration server and source code repository by Microsoft■Tinderbox — Mozilla-based product written in Perl■Rational Team Concert — proprietary software

development collaboration platform with built-in build engine by IBM including Rational Build Forge

Software tools for continuous integration include:■AnthillPro — continuous integration server by Urbancode■Apache Continuum — continuous integration server

supporting Apache Maven and Apache Ant. Supports CVS, Subversion, Ant, Maven, and shell scripts■Apache Gump — continuous integration tool by Apache■Automated Build Studio — proprietary automated build,

continuous integration and release management system by AutomatedQA■Bamboo — proprietary continuous integration server by

Atlassian Software Systems■BuildBot — Python/Twisted-based continuous build

system■BuildMaster — proprietary application lifecycle

management and continuous integration tool by Inedo■CABIE - Continuous Automated Build and Integration

Environment — open source, written in Perl; works with CVS, Subversion, AccuRev, Bazaar and Perforce■Cascade — proprietary continuous integration tool;

provides a checkpointing facility to build and test changes before they are committed■codeBeamer — proprietary collaboration software with

built-in continuous integration features■CruiseControl — Java-based framework for a continuous

build process■CruiseControl.NET — .NET-based automated continuous

integration server■CruiseControl.rb - Lightweight, Ruby-based continuous

integration server that can build any codebase, not only Ruby, released under Apache Licence 2.0■ElectricCommander — proprietary continuous integration

and release management solution from Electric Cloud■FinalBuilder Server — proprietary automated build and

continuous integration server by VSoft Technologies■Go — proprietary agile build and release management

software by Thoughtworks■Jenkins (formerly known as Hudson) — MIT-licensed,

written in Java, runs in servlet container, supports CVS, Subversion, Mercurial, Git, StarTeam, Clearcase, Ant, NAnt, Maven, and shell scripts■Software Configuration and Library Manager — software

configuration management system for z/OS by IBM Rational Software■QuickBuild - proprietary continuous integration server

with free community edition featuring build life cycle management and pre-commit verification.■TeamCity — proprietary continuous-integration server by

JetBrains with free professional edition■Team Foundation Server — proprietary continuous

integration server and source code repository by Microsoft■Tinderbox — Mozilla-based product written in Perl■Rational Team Concert — proprietary software

development collaboration platform with built-in build engine by IBM including Rational Build Forge

➡Humans should do the intelligent work➡Integrate with source code, metrics

Continuous Integration

473 plugins

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡Sonar

http://sonarsource.org/

➡For managers?

Metrics

★Checkstyle★PMD★ Findbugs★ Cobertura★ Emma★ Clirr★ JaCoCo★ Useless Code★ SQALE★ 20+ others...

#Maven 2 or 3

mvn sonar:sonar

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡BTrace

http://kenai.com/projects/btrace

➡Bytecode, class manipulation➡Aspect-like adjustment at runtime

Runtime Inspection

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import com.sun.btrace.AnyType;import java.lang.management.MemoryUsage;import java.util.concurrent.atomic.AtomicInteger;import java.util.Map;

@BTrace public class TraceAllMethodCalls { /** * METHOD CALL TRACEPOINT. */ @OnMethod( clazz="com.ambientideas.HelloWorldJava", method="print", location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/") ) public static void m(AnyType[] args) { //System.out.println("Hello"); println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } @OnMethod( clazz="/.*/", method="println" ) public static void m2(AnyType[] args) { println(strcat("****** WE'VE ENTERED A METHOD ON CLASS: ", name(probeClass()))); println(strcat("****** WE'VE ENTERED METHOD: ", probeMethod())); } /** * ONEXIT TRACEPOINT. CALLED WHEN A BTRACE METHOD CALLS EXIT(INT). */ @OnExit public static void onexit(int code) { println("****** THE BTRACE PROGRAM IS EXITING."); }

/** * LOW MEMORY TRACE POINT. */ @OnLowMemory( pool = "Tenured Gen", threshold=58720250 ) public static void onLowMem(MemoryUsage mu) { println("******"); println(mu); } /** * MEMORY HISTOGRAM TRACE POINT. */ private static Map<String, AtomicInteger> histo = newHashMap();

@OnTimer(4000) public static void print() { if (size(histo) != 0) { printNumberMap(strcat("******", "Component Histogram"), histo); } }}

➡Gradle

➡Jenkins

➡Sonar

➡Maven 3

➡VisualVM

➡BTrace

➡VisualVM

http://visualvm.java.net/

➡Java 1.4 through Java 7 support➡Included in JDK 6u7 >

Virtual Machine Metrics

Build Lifecycle Craftsmanship

at the Transylvania JUG

by Matthew McCullough