GlassFish 3.1

Idag släpptes applikationsservern GlassFish 3.1. Det mycket i den releasen som är värt att titta noga på och även om applikationsservrar ända sedan J2EE har haft svårt att få acceptans i systemutvecklarkretsar. Val av applikationsserver är ett strategiskt val, det är viktigt att man som företag “satsar på rätt häst”, efter som det är stor sannolikhet att man får leva med valet i flera år framöver.
GlassFish är referens implementation till Java EE specifikationen. Det betyder konkret att GlassFish alltid kommer ligga i framkant när Java och Java EE standarden utvecklas. När detta skrivs är vi på Java EE 6, en standard som innehåller väldigt mycket som höjer abstraktionsnivån på hur avancerade system utvecklas GlassFish är i dagsläget enda applikationsservern som implementerar hela Java EE 6 standarden. Standarden kräver att applikationsservern sköter det mesta av det som man för bara några åt sedan var tvungen att hacka mängder med XML för att få till. Man har tagit best practices från ramverk som Spring, Hibernate, Google Guice och Seam för att bygga upp en programmeringsmodell som bevisligen fungerar. GlassFish är således verkligen en plattform för att programmera på ett effektivt sätt.
GlassFish är ombyggd från 2.x versionen till att vara helt modulär och baserad på OSGi plattformen Apache Felix. Det betyder konkret att man har en plattform som är modulär och där man bara behöver köra de moduler som verkligen behövs. Det betyder dessutom att det är enkelt att vidareutveckla plattformen med OSGi boundles som deployas på Felix. GlassFish kan till och med interagera med OSGi boundles via injections i Java EE applikationer (sk. Hybridapplikationer).
GlassFish har i och med 3.1 åter fått stöd för klusting och central administration. Det är goda nyheter för företag med stora data centers som behöver en bra överblick över installationer och miljö och en hög tillgänglighet. Kort sagt, GlassFish tillför så mycket värde att det kanske, nästan överväger debaclet med Oracle -> Sun.

Att utveckla för driftbarhet

Ordet systemutveckling syftar till att handla om mer än programmering av affärslogik. Det syftar till att utveckla systemet som ska skapa affärsvärde. Har man väl vridit hjärnan till ett sådant tankesätt, är det lätt att ta till sig att saker som hur loggar skrivs ut potentiellt kan vara en väldigt viktig del av programmeringen. Den stackars jourpersonen som kl 03 ska försöka reda ut varför företaget plötsligt blöder pengar, vill nog gärna att Nagios, Hyperiq eller vad man nu använder; triggas på rätt sätt. Övervakningssystem som dem tittar ofta på loggar för att rapportera fel. Det betyder att loggar potentiellt kan vara väldigt viktiga == bör testas! Nedan visas ett exempel på hur vi gjorde ett enkelt test för att verifiera själva logutskriften hos en kund.
Vi tänker oss att vi har en service “MyService” som använder sig av en wrapper “RemoteProviderWrapper” för att anropa en extern tjänst av något slag.

package se.diabol.test.logunit
import org.apache.log4j.Logger
class MyService {
  private Logger log = Logger.getLogger(MyService.class)
  RemoteProviderWrapper remoteProviderWrapper = new RemoteProviderWrapper()
  void shakyServiceMethod(String parameter){
    try{
      remoteProviderWrapper.callRemoteProvider(parameter)
    }catch(RemoteProviderCommunicationException e){
      log.error "Communication failure with external provider: ${e.message}"
      // Do cleanup, rollback transactions, report to the user..
    }
  }
}

Om man tittar vi på vad som händer i själva catch blocket (jag är fullt medveten om att det inte är optimalt att lösta exception hantering på detta sätt, men det är bara ett exempel). Det skrivs ut ett felmeddelande som talar om att det inte går att kommunicera med den externa tjänsten. Denna loggutskrift är guld värd för någon som, utan programmerardjup kunskap om systemet, ska förstå vad som är roten till problemet. Hela systemet kan ju just nu stå och kräkas ur sig stackutskrifter från exceptions. Antagligen finns det en trigger i övervakningssystemet på denna logutskrift. Alltså bör vi testa att detta logmeddelande verkligen kommer ut som en del i vårt testramverk. Jag har skapat en log4j appender som sväljer alla meddelenaden för att senare i en testkod kunna hämta ut dem och verifiera vad de innehåller:

package se.diabol.test.logunit
import org.apache.log4j.AppenderSkeleton
import org.apache.log4j.spi.LoggingEvent
class UnitTestAppender extends AppenderSkeleton { 
  private List messages = []  
  protected void append(LoggingEvent event) {    
    messages += event.renderedMessage  
  }  
  void close() {}  
  boolean requiresLayout() {return false}  
  String[] getMessages() {
    return messages as String[]
  }
  void clear() {
    messages = []
  }
}

Ok, nu har vi en appender, då är det bara att tala om för log4j att den ska användas (sätter det på root loggern här)

log4j.rootCategory=DEBUG, junittestappender
log4j.appender.junittestappender=se.diabol.test.logunit.UnitTestAppender

Därefter kan man skriva ett unittest som använder appendern för att verifiera loggningen som sker i koden.

package se.diabol.test.logunit

import org.junit.Test
import groovy.mock.interceptor.*
import org.apache.log4j.LogManager

class MyServiceTest {
    @Test
    void makeFailedCallToRemoteProvider(){
        def appender = LogManager.rootLogger.getAppender("junittestappender")
        appender.clear()

        def mock = new MockFor(RemoteProviderWrapper.class)
        mock.demand.callRemoteProvider { throw new RemoteProviderCommunicationException("Communication link down!")}
        mock.use{
            new MyService().shakyServiceMethod("Test parameter")
        }

        assert appender.messages == ["Communication failure with external provider: Communication link down!"]
    }
}

Jag börjar med att hämta ut den appender som log4j har skapad och tömmer eventuella gamla meddelanden “clear()”. Sen använder jag grooys inbyggda mockningsfunktionalitet för att skapa en mockad “RemoteProviderWrapper”. Denna mock kommer skicka ett “RemoteProviderCommunicationException” varje gång den anropas. Innanför “mock.use{” blocket kommer alla försök att skapa en “RemoteProviderWrapper” returnera den mock jag angivit ovanför. Jag behöver alltså inte tala om för MyService att den ska använda den mockade klassen på något annat sätt. Sen anropar jag service metoden “shakyServiceMethod”. När det är gjort, hämtar jag ut allt som lagrats i test appendern och verifierar att en logutskrift verkligen skett.
Vad var nu sysftet med detta? Jo, plötsligt har blicken lyfts lite. Här finns en tanke om att det inte bara är själva koden som är viktigt. Denna kod sitter antagligen i någon modul som ingår i ett system. För modulen och programmeraren är loggningen helt irrelevant. Men för systemet och verksamheten kan det vara fråga om skillnader i timmars felsökning för att hitta en extern tjänst som gått ner, eller se ett korrekt felmeddelande i övervakningssystemet. Det är vad utveckling för driftbarhet handlar om.
Nästa steg är att även involvera nämnt övervakningssystem i systemutvecklingen och börja göra automatiska funktionstester som även omfattar övervakning.

Myten om kvalitetskompromissen

Alla som har hört frasen “varför är det så svårt att få produktägare att prioritera kvalitet istället för att trycka in massa funktioner hela tiden!” räcker upp en hand. — Ok ta ner.

Att hålla hög kvalitet är ingen trade-off eller kompromiss i systemutveckling. Det är inte ens förenat med en extra kostnad! Varför? Jo, för i systemutveckling går produktionstaken upp betydligt om systemet håller hög kvalitet. Har systemet dessutom ett test ramverk, som hjälper systemutvecklare att göra rätt, ökas möjligheten till kontinuerlig förbättring och därmed ytterligare kvalitet väsentligt. Att kvalitet skulle vara något man kan byta mot mer funktionalitet är därför helt felaktigt. Med högre kvalitet kommer istället mer funktionalitet. Det här skiljer sig ju från den gängse normen att “man får vad man betalar för”. Det fungerar inte riktigt på samma sätt i systemutveckling, här är det snarare: “Har man dålig kvalitet i sitt system får man betala mer!” och vilken produktägare skulle vilja betala mer för mindre om detta tydliggjordes?

Men hur får man då hög kvalitet i sitt system om man inte redan har det? Ja, det är här det börjar bli komplicerat. Hade detta varit enkelt hade det antagligen inte funnits system som håller dålig kvalitet, för alla vill ju göra ett bra jobb. Men det är en systemutvecklares skyldighet att införa förändringar som inte försämrar, utan snarare ständigt förbättrar kvalitet i de system de jobbar med. Advokater, Läkare och Mäklare är exempel på yrken som håller sig med förbund för att upprätthålla en god kvalitet i respektive bransch (den sistnämnda vet jag inte om de lyckas så bra). Här jobbar man ständigt med övergripande mål och förbättringar. Något motsvarande finns inte inom systemutveckling, men lika fullt är det viktigt att upprätthålla god kvalitet. Man kan dra det så långt som att det är viktigt för samhället och utvecklingen av landet att detta görs bra av oss som bor här – men det blir kanske lite högtravande.

Systemutveckling vs Lean manufacturing

På senare tid har det höjts fler och fler röster (jag är ingen journalist, så jag slänger mig med en sån, istället för fakta) som förespråkar att man använder principer från Lean manufacturing i sin systemutvecklingsprocess. Det är en mycket god idé, men långt ifrån en fullständig lösning. Jag ska försöka underbygga varför det inte fullständigt här.

Lean Manufactoring har en lång historia bakom sig. Toyota production system skapades under 35 år av Taiichi Ohno genom hans erfarenhet från tygfabriker innan han stod på golvet i Toyota. Det är därför ganska naivt att tro att vi på några år ska kunna hitta en perfekt process för systemutveckling. Idag sitter många organisationer fast i en vattenfallsinspirerad organisation med olika avdelningar för utveckling, test och drift. I en sådan organisation kan en bok om Lean software development kännas som vägen till himmelriket. Dock finns det anledning att vara försiktig.

Det är viktigt att komma ihåg vad målsättningen är med Lean Manufactoring. Att skapa ett system som reglerar produktionstaken efter efterfrågan och ger så stor effektivitet som möjligt i produktionen. Kan man relatera det mot syftet för att bedriva systemutveckling? Att införa förändringar i system för att skapa tjänster och funktioner som ger värde åt företag. Inte riktigt. Det finns en viktig komponent i systemutveckling som inte alls ingår i Lean manufacturing. Det är ganska uppenbart om man tittar på det sista ordet “manufacturing” – tillverkning kontra utveckling i det andra fallet. I tillverkning är det underförstått att själva utvecklingen redan är gjord. En bil är ju redan designad och konstruerad innan tillverkningen ens har påbörjats. Vad betyder då det? Jo dels att varje iteration behöver innehålla en god del modellering, forskning och innovation och dels att det behövs utrymme för betydligt mer kreativ frihet än i en fabrik som producerar bilar. Detta ingår inte alls som en komponent i Lean manufacturing, det till och med motarbetas. Vad blir konsekvensen av det? Ja alla som har suttit i utvecklingsprojekt med otydligt arkitektur och som saknar tid för kreativ innovation vet var som händer med systemet som produceras på lång sikt. Det bildas ett vårtsvin – ett system som är lappat och trixat med för att införa funktioner under tidspress.

Vad är då lösningen? Den som kommer på det vinner en resa till Bahamas, som han/hon får betala själv. Men en viktig sak är att titta på helheten och inte fokusera på att optimera saker långt ner i kedjan som med stor sannolikhet är en suboptimering. Datamodellering, processkartläggning för verksamheten kan enkelt reducera hela it system som kanske kostar en förmögenhet att underhålla. Refaktorering av ett system med för många datalager kan skära bort 80-90% av fullständigt irrelevant konverteringskod.

Taiichi Ohno säger att den värsta formen av “waste” är “waste som döljer waste”. Framtagningen av ett onödigt delsystem kan skapa massvis med waste som går att reducera enligt konstens alla regler, men om man tar bort hela delsystemet är alla förbättringar förgäves, Lean eller inte.

Summering: Principer från Lean är mycket bra! Men det är långt ifrån hela sanningen. Vi får inte glömma helheten i systemutveckling. Ordning på modeller, ordning på systemarkitektur och utrymme för kreativ innovation som kontinuerligt förbättrar systemen. Eric Evans sa detta på senaste JFokus: “Every release is a preparation for the next one”.

DevOps movement

Patrick Debois – jag vill skicka ett tack för att du sett mig! De senaste åren har jag haft stora problem att definiera mig själv och vad min roll är som konsult. Jag märker hur jag börjar svamla lite när kollegor frågar vad jag gör, även om jag alltid vetat att det jag gör och strävar efter har varit helt rätt och mycket viktigt! Jag visste inte vad som saknades innan jag för några månader sedan kom över en presentation från Patrick Debois som definierade en helt ny yrkesroll – DevOps. Plötsligt föll allt på plats! Det var otroligt, det finns fler som jag och några av mina kollegor på Diabol. Fler som förstår att systemutveckling kan göras mycket mer effektivt än vad vi generellt sett gör idag.

Jag har under flera år arbetat som DevOp utan att själv veta om det. Vägen dit för mig har varit via 10+ års Enterprise Java utveckling via en renodlad Applikationsserver (GlassFish) expert som mer naturligt hör till operationsavdelningen och i och med det, en insikt i hur lite dessa två avdelningar (utveckling och operations) pratar med varandra. En brist på kommunikation som är oerhört kostsam.

Det var det första biten som jag började slipa på, men det kändes som att försöka nysta upp en bäverfördämning det var så cementerat att det inte gick med några nya verktyg och välformulerade emails. Det måste in mer tungt artilleri. Ledningen måste förstå problemet och verkligen vilja göra något åt det, så kulturen i företaget ändras i grunden. När man väl är där inser man plötsligt att Developer – Operations problematiken bara är en liten topp av isberget. Det är här hela DevOps rörelsen kommer in på scenen. En DevOp definierar och bygger fabriken som ska producera systemet. Hela flödet, från hur business value bäst omhändertas, idéer och features hanteras, förändringar (koden, konfiguration), kvalitetssäkring och produktionssättning genomförs så effektivt som möjligt. Kultur, process och teknik (tools). Det nya är insikten att detta arbete har ett fundamentalt värde för företaget. Lika stort värde, om inte större än själva systemet som sitter i produktion. Ju bättre detta arbete görs, ju enklare blir det för företaget att kostnadseffektivt och med hög kvalité låta systemen följa företagets och dess marknads utveckling. Bilfabriker har länge slipat på detta. Produktionskostnader, omställningskostnader, kvalitetskostnader, materialkostnader, arbetande kapital, lagerkostnader.. allt är begrepp som är precis lika relevanta för en systemutvecklande it-avdelning, men som det talas alldeles för lite om. Ännu mindre görs något åt. Det man talar om istället är kostnader för löner och timpris på programmerare. Blir det för billiga, så kvaliteten går ner, skickar man utan att blinka in flera testare som åtgärd. Begrepp man hör som buggrättningsperioder, entrycriterias, överlämning, manuellt regressionstest, uppstädnings sprintar, omskrivning, maintenance fönster, planerad nertid, patch release, etc, är alla begrepp som borde generera en stor varningsklocka hos produktägrana: “Varför ska vi lägga tid och pengar på det?”. Nej in med ny kultur, automatiska tester, constant improvement, autmatic deploys, continuous delivery, multifunktionella team, pragmatisk arkitektur. Det är business value!

Enterprise 2.0

Vad är enterprise 2.0? – Jo det är början på en framtid som kommer ändra systemutveckling i grunden. Hur? – Genom att företag som använder enterprise 2.0 kommer att sopa banan med konkurrenter!

Men vad ÄR enterprise 2.0 då? Enligt min egen definition är det möjligheten att skapa system som hanterar stora mängder transaktioner (< 10000 om dagen) samtidigt som förändringar aldrig tar längre än en sprint att införa.

Det krävs att en mängd saker finns på plats för att det ska vara möjligt, men idag är det endast en bakåtsträvande eller möjlgen en “J2EE bränd” organisation som inte ser och tar den möjligheten. Med J2EE bränd menar jag en organisation som för ca 10 år sedan satsade enorma summor på att bygga en arkitektur enligt J2EE och upptäckte att den var värdelös aldeles för sent.

Vi lever i en ny tid idag, ramverken är bättre, teknikerna är bättre, hårdvaran är bättre och kanske framförallt JVM är bättre än den någonsin varit. Så vad krävs då för enterprise 2.0. Jo, framförallt två viktiga saker – Kreativitet och självförtroende! Kreativitet att bygga system som är enkla nog att underhålla samtidigt som man hela tiden inför ny funktionalitet. Självförtoende att ständigt förbättra -refakrorera- systemet (inom en sprint) utan att behöva tänka att “något kanske går sönder”. Det låter kanske enkelt, men det kräver mycket arbete för ett team att nå dit. Test driven utveckling, continuous integration som tar hand om alla byggen 100% autmatiskt, omfattande testramverk men automatisk regressionstest. Men även ett stort medvetande hos utvecklare hur produktionsmiljön faktiskt ser ut.

För att tydliggöra var jag menar med kännedom om produktionsmiljö: Det krävs till exempel kännedom om övervakningssystem och larmhantering. Ska ett system ut i produktion samma dag som sprinten är slut, håller det inte att börja anpassa ett övervakningssystem i efterhand. Det är en del av systemet och därmed en del av utvecklingen och ska utföras av det multifunktionella teamet i sprinten. Alla saker som idag normalt sett ligger utanför sprinten måste få plats i! Test (unit, integration, regression, last), byggen, konfigurering, acceptans, vaildering, etc. Det är svårt!

Tänk den företagsledare som får en idé som klart förbättrar konkurrensläget, som har en IT avdelning som kan leverera idéer ut mot kund på fyra veckor! Det är en ledare med en guldmotor i bolagen som endast begränsas av sin egen kreativitet för att nå framgång. – Det är enterprise 2.0!

Groovy och Grizzly http unit test

Hur ofta är det inte som man stöter på legacy kod som vill göra ett externt TCP anrop (socket, http, webservice eller något annat) och så sliter man sitt hår för att hitta det optimala sättet att skriva ett unit test för koden (som naturligtvis inte finns där från början) för att kunna göra den lite mindre legacy.

Jag stötte på detta igen häromdagen och bestämde mig för att testa ett groovy-grepp på problemet. Det visade sig vara en strålade idé (ödmjukt).

Säg att vi har följande lilla demoklass att testa.

package demo;

import java.io.IOException;
import java.net.HttpURLConnection;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

public class HttpCallingBean {    

    public void sendMessage(String message) {
        HttpClient httpClient = new HttpClient();
        PostMethod postMethod = new PostMethod("http://localhost:8282");

        try {
            StringRequestEntity entity = new StringRequestEntity(message);
            postMethod.setRequestEntity(entity);
            httpClient.executeMethod(postMethod);
            if(postMethod.getStatusCode() != HttpURLConnection.HTTP_OK){
                throw new RuntimeException("Not ok!"); // Only a demo...
            }

        }catch(IOException e){
            e.printStackTrace(); // Only a demo...

        }finally{
            postMethod.releaseConnection();
        }
    }
}

Vill vi skriva ett test för detta (utan att bryta ut anropet i en annan klass och mocka den) så måste vi sätta upp en liten lyssnare på porten 8282 på localhost, vi vill dessutom integrera detta i junittestet så att lyssnaren startas och stoppas tillsammans med tester. Med Grizzly och Groovy visar det sig att detta är mycket enkelt. Nedan följer testkoden för klassen ovan

package demo

import groovy.util.GroovyTestCase
import com.sun.grizzly.http.SelectorThread
import com.sun.grizzly.tcp.Adapter
import com.sun.grizzly.tcp.Request
import com.sun.grizzly.tcp.Response
import com.sun.grizzly.util.buf.ByteChunk
import java.net.HttpURLConnection

class HttpCallingBeanTest extends GroovyTestCase {

 void testSayHello()throws Exception {
 def st = new SelectorThread()
 try{
 st.port = 8282
st.adapter = new BasicAdapter()
 st.listen()

 HttpCallingBean beanUnderTest = new HttpCallingBean()
 beanUnderTest.sendMessage("Hello grizzly")

 }finally{
 st.stopEndpoint()
 }
 }
}

class BasicAdapter implements Adapter {
 public void service(Request request, Response response) {
 def content = new ByteChunk()
 request.doRead(content)
 def bytes = null
 if(content.equals("Hello grizzly")){
 response.status = HttpURLConnection.HTTP_OK
 bytes = 'Success'.bytes<strong>
 }else{
 response.status = HttpURLConnection.HTTP_BAD_REQUEST
 bytes = 'Failure'.bytes
 }

 def chunk = new ByteChunk()
 chunk.append(bytes, 0, bytes.length)
 response.contentLength = bytes.length
 response.contentType = 'text/html'
 response.outputBuffer.doWrite(chunk, response)
 response.finish()
 }

 public void afterService(Request request, Response response) {
 request.recycle()
 response.recycle()
 }

 public void fireAdapterEvent(string, object) {}
}

Här har vi alltså ett unittest som startar en Grizzly SelectorThread och kopplar en enkel adapter (BasicAdapter) till den. Adaptern läser vad som kommer in och svarar med OK eller BAD_REQUEST. När testet är kört stoppas selector tråden i finally blocket och vi har ett komplett test för bönan med dess externa anrop i ett enda unittest.

Reflektion om produktionstakt

Jag har varit systemutvecklande konsult i tunga transaktionsintensiva projekt i över 10 år nu. Det är dags att börja göra några summeringar och reflektioner. Jag tror vi kan göra många saker mycket bättre!

Utvecklingen har verkligen tagit jättekliv sedan 1998. Du patchade man system direkt i produktion även om de var kritiska för versamheten. CVS var en uppstickare. Java var “för långsamt” och UML var det nya och heta som alla skulle använda, gärna i RUP projekt. CORBA och business components var framtiden!

Men då kom revolutionen – J2EE! Nu skulle man fokusera på business logik och inte tänka på något annat. Komponenter skulle produceras med en rasande hastighet för att jackas in i applikationsservermiljöer som automatiskt kunde kopplas mot vilket “legacy” system som helst. Men vi vet ju alla vilken vändning detta tog.

Faktum är att jag håller med Rod Johnson när han talar om “the dark years of enterprise java”. Även om många tagit klivet ur J2EE till förmån för Spring eller Java EE är det tyvärr mycket som lever kvar från den tiden. Objektorientering är helt borttappad, en mängd olika lager existerar för att lösa J2EE problem som ju inte finns längre, ägare och CM är livrädd för förändringar, domänmodell är inget man arbetar med över huvud taget, systemen växer på alla breddar istället för att kontinueligt justeras efter en verksamhet.

Men vad värre är att utvecklarna ses som skurkarna i många projekt idag. Man vill gärna bädda in dem i en mängd testare, QA-personer, driftpersoner, avlämningsdokument, junittestrapporter och kodgranskningar för att lösa ett problem som inte längre behöver existera! Tänk vad allt detta kostar. Hur mycket tid kan en modern systemutvecklare igentligen lägga på att producera vettig kod??

Men jag förstår personerna som bäddar in utvecklarna, lika mycket som jag förstår utveklarna som inte gnäller på detta. Utvecklingsteam har med J2EE producerat oanvändbara system i många år, de klarar inte pressen! Samtidigt som produktägarna har dåligt förtroende för teamen. De är trötta på att få höra att det tar upp till fyra månader att få ut sin lilla feature som gör att denne kan fånga den där viktiga kunden.

Därför borde vi, som tycker att detta nära nog är en samhällsekonomisk katastrof, göra uppror och visa projekten vi deltar i att idag kan vi producera system som håller betydligt högre kvalité till betydligt lägre pris, om vi bara får ansvaret att göra det!

Men ANSVAR är huvudordet här! En systemutvecklare som suttit inbäddad på detta sätt länge har glömt att det är det som kodas in i systemet som bestämmer hur bra det fungerar. Det gör inte hur många buggar man “lyckas” hitta i oändliga testperioder, eller hur lite tid en överdimensionerad driftavdelning har systemet nere. Det är hur få buggar som byggs in och framförallt, hur mycket systemet klarar sig självt i produktion som bestämmer hur väl utvecklingsteamet klarar uppgiften, helst utan någon systemtest utanför teamet.

Jag är säker på att frånvaron av alla timmar som lägs på överlämningsdokument och testmöten, skulle kunna halvera kostnader i många projekt om bara utvecklarna tog ansvar och produktägarna började lita på dem.

We Continuously Deliver!