Olle Hallin

Olle Hallin

Om systemutveckling i största allmänhet

Why you should do Continuous Code Cleansing

First we had Continuous Integration. It solved the problem of uncontrollable snowballing integration phases at the very end of development projects.

Then we learned about Continuous Delivery and Continuous Deployment. They make putting new features into production a risk-free no-brainer.

Now it’s time to learn about Continous Code Cleansing!

It is about continuously making sure your code base is as small as possible.

Smaller code base means faster development.

Read more about Continuous Code Cleansing and it’s supporting tool Codekvast at http://codekvast.crisp.se.

YANIA – You Ain’t Needing It Anymore

In the agile community we use the acronym YAGNI to remind ourselves to stay away from building (however cool) stuff that no-one is asking for.

If used wisely, the YAGNI veto will help teams maintain velocity over time and let them focus on delivering true business value early and often.

Now when we start adopting Lean Startup principles, it’s time to learn a new acronym: YANIA!

read more »

Alla mjukvaruprojekt borde ha en Kodkvast!

- “All kod är en skuld!”
– “Den bästa koden är den kod man inte skriver!”
– “Snabbaste sättet att få upp testtäckningen är att ta bort död kod!”

Jag tror att alla är överens om att det är bra att hålla sin kodbas så liten och kompakt som möjligt. Byggtider hålls korta, testsviter går fort att genomföra, driftsättningar går fort, statisk kodanalys går fort, nya teammedlemmar kommer snabbt in i koden, risken för buggar och sårbarheter hålls nere och så vidare. Kort sagt, man blir mer lättrörlig!

Så alla utvecklingsteam borde ägna tid åt att inte bara skriva ny kod, utan också att faktiskt städa efter sig. Men det är lättare sagt än gjort…
read more »

Mitt drömuppdrag

Som frilansande konsult kan man ju oftast inte utforma sina egna uppdrag, utan man får ta det som kommer i ens väg.

Har man tur kan man välja mellan två eller kanske till och med tre olika uppdrag. Har man haft bra beläggning under en tid och lyckats samla i ladorna kan man stå över tills det kommer något bättre i ens väg. Men till slut har man inget val alls utan måste ta vilket uppdrag som helst eftersom skattmas och bolåneinstitut skall ha sitt.

Nu är det inte så illa för mig, men jag tar mig i alla fall friheten att utforma mitt drömuppdrag. Om många vet vad jag drömmer om är ju chansen att det slår in större, eller hur?

read more »

Hur man låter Gradle kolla om man har de senaste versionerna av sina tredjepartsbibliotek

Inledning

Nu för tiden använder nog de flesta Javaprojekt någon sorts dependencyhanterare i sina byggen.

Den tid då man checkade in sina tredjepartsbibliotek i versionshanteringen är förbi. Nu låter man Maven (eller Ivy eller Gradle) läsa en incheckad förteckning, hämta hem jarfilerna ifrån de centrala förråd som finns därute och sätta upp class path.

En sak som dessa verktyg dock inte hjälper till med är att hålla koll på att man inte ligger kvar på gamla versioner. Att köra på gamla versioner kan ses som en sorts teknisk skuld, eftersom det blir värre och värre att uppgradera ju fler versioner man har missat.

Det är dock ett mödosamt och tråkigt manuellt arbete att kolla hur bra man ligger till.

Jag har därför utvecklat en Gradle-task som automatiserar detta!

(Se där, ännu en anledning att byta till Gradle!)

read more »

Hur man kan hantera Continuous Delivery med MongoDB

MongoDB är en schemalös, dokumentorienterad databas som har fått stor popularitet i den agila världen bland annat därför att man inte behöver underhålla något databasschema.

MongoDBs schemalöshet gör att många leds att tro att Continuous Delivery blir en promenad i parken, eftersom det ju inte behövs några datamigreringar när man driftsätter en ny version av koden!

Rent teoretiskt är detta sant, men är ett sluttande plan in i Land of Crappy Code™ !

För att slippa onödig komplexitet i form av varierande utseende på lagrade domänobjekt beroende på deras ålder, rekommenderar jag att man utför regelrätta datamigreringar även när man använder MongoDB!

Jag rekommenderar även att datamigreringen är en del av applikationen — till skillnad från skript som skall köras vid sidan av innan applikationsstart — helt enkelt för att eliminera risken för misstag.

Jag har i mitt sidoprojekt Varmfront.nu utvecklat en kompakt liten lösning som i MongoDB implementerar det som Flyway gör för SQL.

Mönstret bygger på Spring Data for MongoDB och Spring JavaConfig, och migreringarna är skrivna i Java. That’s right folks, no XML here :D

Läs vidare, så får du se hur man kan göra!

read more »

Äventyr i molnet – del 4

Jag ber om ursäkt för det långa uppehållet sedan förra delen. Förklaringen stavas Valle. Valle är en hund, närmare bestämt en Lagotto Romagnolo. Valle är nu snart ett år gammal, så nu har jag “fritid” igen. Wohoo!

Denna gång skall det handla om något som så gott som alla webappar behöver, nämligen användarhantering och autenticering.

Handen på hjärtat, visst vore det skönt att kunna plugga in en färdig användarhantering, och kunna låta folk logga in med sina redan existerande Facebook/Google/Windows Live/Twitter/whatever-konton?

Om svaret är ja, läs vidare!

OpenID

Det finns en standard för tredjepartsautenticering som heter OpenID, som så gott som alla stora sociala nätverk stödjer.

Problemet med OpenID är att det är ganska pilligt att få på plats, och det är inte helt uppebart för en användare hur han skall logga in med sitt OpenID.

Ett annat problem är att alla sociala nätverk har olika API:er för att hämta användardatat, efter att själva autenticeringen är klar.

Du måste dessutom bygga själva logindialogen själv. Detta är inte speciellt svårt, men ändock ett jobb.

Här kommer Janrain till din räddning!

Janrain

Janrain är en mäklare för tredjepartsautenticering.

De säger själva att de erbjuder användarhantering som en Software-as-a-Service (SaaS).

Janrain erbjuder ett uniformt API för att accessa de olika sociala nätverk som de stödjer. Det är dock vissa skillnader på vilka data om en användare som de olika nätverken lämnar ut. Till exempel så lämnar LinkedIn inte ut epostadresser, vilket åtminstone Google, Facebook och Windows Live gör.

Med Janrain är det lätt att lägga till användarhantering. Det går i princip till så här:

  1. Registrera din app på janrain.com. Du kan logga in med vilket som helst av dina sociala konton (Janrain äter sin egen hundmat!)
  2. Ange vilka sociala nätverk du vill använda för autenticering.
  3. Kör en wizard på Janrain som genererar en snutt Javascript som du kopierar in till din webbsida, omedelbart före .
  4. Wizarden genererar också en kodsnutt för HTML-länken Logga in…
  5. Implementera en callbackrutin som anropas av Janrain när en användare har autenticerat sig. URL:en till denna callbackrutin bestämmer du själv, och du anger den i wizarden i steg 3.
  6. Callbackrutinen anropas av Janrain med en HTTP POST som har en enda parameter, token. Denna token använder du tillsammans med den applikationsidentitet som du fick i steg 1 för att anropa ett Janrain API för att hämta användarinfon. API:et är en vanlig HTTP POST, som returnerar användardatat antingen i XML- eller JSON-format.

Klart!

Nu har du en komplett användarhantering, och dina användare kan direkt logga in och börja använda din sajt.

Klick på loginlänken öppnar en dialogbox som automatgenereras av Janrain-scriptet. I denna dialog kan användaren välja vilket nätverk han vill logga in på din sajt med.

I användardatat du får tillbaka från Janrain ingår en globalt unik OpenID-identitet. Denna kan du använda som nyckel för de applikationsspecifika användardata du vill spara i din egen databas. Du behöver inte lagra själva användardatat (namn, epostadress och så), för det får du ju serverat på nytt varje gång någon loggar in till din sajt.

Vill du stödja ett nätverk till? Logga in på janrain.com och ändra i kontrollpanelen för din app. (I många fall måste du dessutom registrera din Janrain-app hos nätverket i fråga.)

På janrain.com har din app en egen kontrollpanel där du kan se statistik på inloggningarna. Troligen inte det första du skulle bygga om du byggde användarhanteringen själv.

Funktioner för registering, glömt lösenord med mera finns ju redan på de olika sociala nätverken, så det slipper du också bygga.

Så sammantaget får du en komplett användarhantering på några timmar!

Så vad kostar det?

Det här låter för bra för att vara sant, det måste finnas en hake. Det kostar säkert skjortan?

Janrain kör med principen första silen gratis, dvs det är kostnadsfritt upp till 2500 unika användare och 6 st sociala nätverk.

För 100 USD/år kan du ha 5000 unika användare, och 12 sociala nätverk. Då får du dessutom tillgång till mer användardata än i gratisvarianten.

Räcker inte detta finns ytterligare en variant, men prislappen på denna är inte publicerad.

(Om det går så bra så att du får fler än 5000 unika användare är det bara att gratulera! Du har säkert råd med nästa nivå…)

Mönster för flertrådade enhetstester

Detta är ett designmönster för hur man skriver ett enhetstest som utför samma test samtidigt i flera trådar.

Genom att utnyttja java.util.concurrent på ett smart sätt säkerställer man maximal samtidighet, vilken kan avslöja trådbuggar.

Kom ihåg: det går inte att bevisa att ett program är fritt från trådbuggar. Det handlar om att göra det sannolikt att det fungerar i en flertrådad miljö.

Kodmall



    @Test
    public void testSomething() {
        assertTrue(true);
    }

    @Test
    public void testConcurrentAuthInfoResponse() throws InterruptedException {
        final int threads = 100;

        final CountDownLatch readyToStart = new CountDownLatch(threads);
        final CountDownLatch startingGun = new CountDownLatch(1);
        final CountDownLatch finishLine = new CountDownLatch(threads);
        final AtomicInteger failCount = new AtomicInteger();

        for (int i=0; i

Visserligen en hel del boilerplate, men det kan man faktorera ut till en Template á là Springs JdbcTemplate.

Äventyr i molnet – del 3

Inledning

Nu när det finns en första "Hello, World"-version av Eats-o-matic i drift, är det dags att fundera på allvar på den vidare utvecklingen.

För att det skall bli något så behövs det bland annat möjlighet att lagra data, samt ett ramverk för att skapa själva webbapplikationen med.

Jag har kollat igenom ett antal av de alternativ som finns för GAE och kommit fram till ett val som jag tror passar mig som utvecklare och Eats-o-matic som applikation.

Persistens

Vi tar det enkla beslutet först, val av persistensmekanism.

GAE erbjuder två programmeringsgränssnitt för att lagra data: Java Data Objects (JDO ) och Java Persistence Architecture (JPA). (Egentligen finns det ett tredje, lågnivågränssnittet mot Googles egna Big Tables. Men detta tänker jag inte ens beakta, för då har man låst sig hårt mot GAE:s driftsmiljö, vilket bär mig emot.)

JDO är en ganska gammal och beprövad standard, medan JPA är tämligen färskt. Varför JDO inte har fått större spridning förstår jag faktiskt inte. Det passar utmärkt för en stor mängd av tillämpningar. Det är heller ingen brist på effektiva, billiga och stabila implementationer.

(Vissa elaka tungor i blogosfären säger att Sun tog fram JPA efter starka påtryckningar från de ledande RDBMS-leverantörerna, vars produkter inte fungerar så bra med JDO.)

JDO togs ursprungligen fram som ett standard-API för att lagra data i stort sett vilket medium som helst, medan JPA mer eller mindre förutsätter att datat skall lagras i en relationsdatabas.

I GAE så hamnar datat i bägge fallen i BigTable, som varken är en objektdatabas eller en relationsdatabas.

I GAE så används i bägge fallen DataNucleus som verktyg för att vid byggtillfället modifiera dina persistenta klasser så att de går att lagra. Så valet mellan JDO och JPA avgörs av vilket API som passar applikationen bäst.

Jag har jobbat en del med JPA och Hibernate och MySQL, vilket inte var helt friktionsfritt. Det märks att objekt inte är rader i en tabell, utom i det mest triviala fallet. (Jag har lusläst Hibernatedokumentationen flera gånger, och är fortfarande inte säker på att jag förstår allt som står där…)

Jag har även jobbat med db4o, vilket var betydligt mer rättframt. db4o och JDO har väldigt lika programmeringsmodeller.

Så jag satsar mina pengar på JDO.

Kombon JDO + DataNucleus är speciellt tilltalande, eftersom DataNucleus kan använda i stort sett vad som helst för att persistera JDO-objekt; db4o, SQL-databaser, XML-filer, Excel-filer och så vidare.

Detta betyder att jag kommer att kunna enhetstesta min persistenskod mot en lokal db4o-fil, utan att behöva dra igång vare sig en separat db4o-server eller GAE:s integrationtestmiljö. Detta betyder tidsbesparingar!

Som sagt, persistensen överlåter jag med varm hand åt JDO.

Webbramverk

Här är valet betydligt svårare.

Jag är en gammal anhängare av Tapestry, som är ett komponentorienterat ramverk i samma skola som t.ex. Wicket och JSF. Jag har jobbat med Tapestry mer eller mindre kontinuerligt sedan 2003 fram till den dag som idag är.

Tyvärr fungerar inte senaste versionen av Tapestry (5.1) i GAE på grund av Tapestry använder en XML-parser som inte finns med på GAE:s white list.

Wicket lär också ha en del problem i GAE. Jag har bara hört det ryktesvägen och vet inte exakt vad de består i och om de oöverstigliga. Men eftersom jag inte kan Wicket så vill jag inte både lära mig Wicket och ta strulet med att få det att funka i GAE.

JSF har jag stött på i ett projekt, och lärt mig att avsky. Maken till krångligt ramverk får man leta efter. (JSF 2 lär vara bättre, men det har jag inte provat. Jag är inte heller lockad att prova.)

Sedan finns det c:a 100 stycken MVC-ramverk; Spring MVC, Struts, Struts 2 osv. Men har man en gång jobbat med ett komponentramverk så vill man inte tillbaka. Det känns helt enkelt inte bra.

Så mitt val är egentligen ett blindval: jag väljer ett ramverk som garanterat fungerar i GAE och som är komponentorienterat, men som jag aldrig har jobbat med: Google Web Toolkit (GWT).

Att GWT fungerar i GAE tar jag för givet, eftersom bägge är skapade av Google.

Jag har kollegor på Crisp som brukar hylla GWT, och jag litar på dem. Dessutom har jag därmed support på nära håll!

Jag tror även att GWT kommer att passa bra eftersom jag vill att Eats-o-matic skall få ett användargränssnitt mer likt en traditionell applikation än en webbapplikation. Ni vet, drag-and-droptab completion och liknande. Kort sagt, en Rich Internet Application…

Och eftersom jag inte är någon Javascript-guru men kan Java rätt så bra, så hoppas jag på att GWT:s javascriptabstraktion inte läcker allt för mycket, utan håller vad den lovar.

Sammanfattningsvis
Persistens: JDO
Webbramverk: GWT

Äventyr i molnet – del 2

Inledning

Google har en Eclipse-plugin som automatiserar bygge, integrationstest & driftsättning av applikationer för Google App Engine.

Men hur gör man om man liksom jag tycker att det skall gå att bygga och driftsätta från kommandoraden? Eller om man inte använder Eclipse?

Mitt svar är Maven. Tyvärr finns det inte (ännu) någon Mavenplugin, så det blir lite meckigt att få det att fungera.

Varför är detta viktigt?

Missförstå mig inte, jag tycker att det är suveränt att kunna bygga och testa inifrån Eclipse.

Men det är samtidigt väldigt bra att ha ett byggskript som går att köra obemannat från kommandoraden av följande anledningar:

  • Continuous Integration – bygg automatiskt från t.ex. Hudson efter varje incheckning
  • Dokumentation – ditt byggskript dokumenterar på ett körbart och förhoppningsvis portabelt sätt vad som behövs för att kunna bygga och leverera din produkt.
  • Stöd för andra IDE:er än Eclipse. IntelliJ till exempel har mycket bra stöd för Maven.

Varför inte Ant?

Google levererar Ant-stöd för GAE. Jag gillar dock Maven bättre, eftersom det är deklarativt. Beskriv vad du vill uppnå så tar Maven hand om resten. Convention over configuration. Med Ant måste du skriva XML för varenda litet steg i bygget. Ingenting sker automatiskt.

Så vad behövs då för att bygga och integrationstesta med Maven?

Följande förutsättningar måste vara uppfyllda för att det skall gå att 1) bygga, 2) integrationstesta och 3) driftsätta till GAE med hjälp av Maven:

  1. GAEs jar-filer måste vara nedladdningsbara från något Maven-lager (eng. repository).
  2. GAEs integrationstestmiljö måste finnas tillgänglig för Mavens integrationstestfas.
  3. Maven måste instrueras hur man laddar upp den färdiga war-filen till GAE för driftsättning.

Tyvärr är det ingen av dessa punkter som uppfylls på ett bra sätt i dagsläget!

Det finns dock sätt att lösa det:

  1. GAE-jarerna kan installeras i ditt lokala Maven-repo med ‘mvn install-file …’ eller (om ditt företag har ett eget Maven-lager) ‘mvn deploy-file …’
  2. Maven kan delegera till Googles Antskript.

Steg 1 är trivialt, och behöver bara göras en gång per maskin och GAE-version. Steg 2 är det meckiga. En hel del XML blir det…

Hav tröst!

Google brukar publicera sina artefakter på det centrala Maven-repot. GAE-jarerna kommer att finnas där också. Dock oklart när.

Google App Engine-killarna jobbar ihop med "Mr Maven" – Jason van Zyl på Sonatype – med att ta fram en riktigt Maven-plugin som täcker hela utvecklingskedjan.

Så därför har jag bestämt mig för att strunta i integrationstest & deploy från Maven så länge. Jag nöjer mig med att kunna göra det inifrån Eclipse. Projektet är trots allt ett hobbyprojekt, och därmed kan man lägga byggribban lägre.

Härnäst: val av webbramverk och persistens-API

Äventyr i molnet – del 1

Inledning

Det är mycket prat om Cloud Computing nuförtiden. Amazon EC2, Google App Engine, SpringSource CloudFoundry, och nu snart Windows Azure.

Detta är första delen i en serie som beskriver utvecklingen av Eats-o-matic, som kommer att köras på Google App Engine (GAE).

Häng med!

Gör det mest riskfyllda först

En bra princip inom agil systemutveckling är ju att göra det mest riskfyllda först, och i fallet GAE är det naturligtvis att driftsätta sin applikation.

Det här med applikationer i molnet, funkar det verkligen?Har jag brutit mot någon av programmeringsreglerna? Hur hanterar jag applikationen när den väl är i drift? Finns det driftstatistik? Hur kommer man åt loggarna?

Så många frågor, snabbaste sättet att få svar är att testa!

Så jag registrerade ett GAE-konto och skapade applikations-ID:t “eats-o-matic”.

Sedan skrev jag en webbapplikation (host, host), som jag deployade inifrån Eclipse.

Deployförfarandet var löjligt enkelt. Jag klickade på det blåa planet på knappraden, Eclipse frågade efter min GMail-address, lösenord samt GAE-identitet på applikationen.

Så snart applikationen var uppladdad fanns den tillgänglig på https://eats-o-matic.appspot.com.

Så, då var det “svåraste” avklarat!

Om Eats-o-matic

Jag vill inte avslöja för mycket om applikationen i förväg, för då kommer du bara att sno min idé! Men jag kan säga så mycket som att det har med mat att göra.

Å nej, inte ännu en receptsajt!

Lugn, bara lugn. Du kommer att få se! (Se där, ännu en anledning att följa denna blogg…)

Versionshantering i Google App Engine

GAE gör det möjligt att ha flera versioner av samma applikation i drift samtidigt. Man väljer i GAE-konsolen vilken som skall vara default. Detta gör det möjligt att förhandstesta en ny version innan den går live.

Du kan testa detta själv på följande länkar:

  1. https://4.latest.eats-o-matic.appspot.com/ (OBS: webbläsaren kommer kanske att varna för felaktigt SSL-certifikat!)
  2. https://5.latest.eats-o-matic.appspot.com/ (OBS: webbläsaren kommer kanske att varna för felaktigt SSL-certifikat!)

Går du till https://eats-o-matic.appspot.com/ får du den som jag har satt till default.

Alias

Det är ju trevligt om ens applikation har ett namn inom ens egen domän. Detta är väldigt lätt ordnat.
Lägg till ett CNAME som pekar på ghs.google.com i din DNS och lägg till detta alias i Google Apps-konsolen. Så man kommer även åt min app via http://eats-o-matic.hit.se, eftersom min privata Google Appsdomän heter hit.se.

Google Apps och Google App Engine, vad är skillnaden?

Google Apps är en samling molnbaserade tjänster (Software as a Service, SaaS) som Google erbjuder företag och organisationer:

  • Email (GMail)
  • Calendar
  • Chat (Google Talk)
  • Docs (ordbehandling, kalkyl och presentation)
  • Sites (wiki på steroider)
  • Apps (Google App Engine-applikationer)

Så man kan säga att GAE är en delmängd av Google Apps.
Härnäst

Jag kommer att skriva ett nytt blogginlägg varje gång som jag driftsätter en ny version, och skriva något om de erfarenheter som jag har gjort under den “sprinten”. Jag lovar inte någon speciell utgivningstakt, eftersom detta är ett hobbyprojekt. Hoppas ni har förstående för det.

Stay tuned…

Why Are Installers So Slow?

When I started with Windows programming back in 1990-something, Install Shield was de-facto standard. It wasn’t too bad; installations were reasonably easy to create and quick to execute.

Then Windows Installer entered the arena. All the CPU power that Moore’s Law gave us was consumed by Windows Installer.

Even the simplest program takes ages to install. But in most cases, the flow is straight-forward; accept Express installation, accept Terms & Conditions and GO!

Then Adobe entered the arena. Now installers aren’t installers anymore, they are self-extracting CD images!

(Probably created by some InstallEverywhere/InstallAnywhere/InstallNowhere animal that treats internet as some kind of removable CD drive!)

When you double-click the Acrobat Reader installer, it first takes 30-something seconds preparing itself and then launches Windows Installer which adds another 45-something seconds collecting information before finally asking where to install the stuff. Preparing for what and collecting what information? It’s just a PDF viewer for gods sake!

Compare this with Eclipse.

Eclipse doesn’t even have an installer!

Eclipse is distributed as a zip file. Unzip it to any location, send eclipse.exe as a short-cut to the desktop. Done helluvalot faster than the Acrobat Reader installer prepares itself and Windows Installer collects information.

Uninstall is even simpler: just nuke the Eclipse folder. Done.

Installation of multiple Eclipse versions side-by-side: Just unzip them to different folders. Done. No shared stuff that could collide. No dependency to C:WindowsSystem32. Self-contained, reliable.

It’s refreshing to see that installers can be that simple.

Side bar: While I wrote this, I tried the Acrobat Reader installation. It discovered that I had upgraded online, and refused to start. Q: What reasons prevent two different versions of Acrobat Reader in the same machine? A: accidental complexity.