71
Build Lifecycle Craftsmanship at the Transylvania JUG by Matthew McCullough

Build Lifecycle Craftsmanship for the Transylvania JUG

Embed Size (px)

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