dinsdag 31 maart 2009

Java Swing: past, present and future

Swing is de lightweight GUI toolkit voor Java, gebouwd op de AWT toolkit. Beide waren al beschikbaar in een van de eerste versies van de JDK's die door Sun werden uitgebracht. Tot op heden is de Swing toolkit niet helemaal meegeëvolueerd met de rest van de JDK. Het maakt bijvoorbeeld nog geen gebruik van generics en de Event Dispatch Thread (de core-thread van Swing waar alle GUI acties op uitgevoerd worden) is qua code nog steeds zoals deze destijds is opgezet. Dit betekent dat het geen gebruik maakt van de concurrency componenten die vandaag de dag met de JDK geleverd worden. Ook zijn de standaard componenten die bij Swing geleverd worden, zoals JTable, JCombobox, etc, behoorlijk kaal en moet je zelf vaak heel wat code schrijven om component op te maken qua functionaliteit en stijl.

Toch wordt in de tussentijd de toolkit wel bijgehouden. Er worden nog steeds bugs uit gehaald en de performance kan blijkbaar nog altijd beter. Tevens worden er verschillende libraries met generieke componenten in de JDK opgenomen die het programmeren in Swing vergemakkelijken. Dit zijn vaak hoger level componenten, ontwikkeld door Swing gebruikers, die een bepaalde functionaliteit bieden die je anders zelf zou moeten ontwikkelen of steeds overnieuw zou moeten schrijven. Op die manier is er voor Swing applicaties steeds minder boilerplate code nodig omdat je steeds meer componenten tot je beschikking hebt die je standaard kunt gebruiken. Denk hierbij aan de SwingWorker, het TimingFramework en JOGL. De laatste maakt zelfs 3D rendering in Swing applicaties mogelijk!

Swing is van nature een toolkit die basisfunctionaliteit voor grafische applicaties biedt, maar wat niet veel mensen beseffen is dat dit juiste de kracht van de toolkit is. Dat heeft ook Sun ingezien en daarom willen ze in de volgende versie van de JDK (ja ja, versie 7 alweer!) gewoon verder gaan met het optimaliseren van de Swing engine. Tevens wordt er hard aan gewerkt om Swing in steeds meer frameworks te integreren. JavaFX bijvoorbeeld zal Swing componenten kunnen gebruiken voor bepaalde functionaliteit in dergelijke applicaties. Het verder uitbreiden van toepasbare Swing componenten laat Sun lekker over aan iedereen die hier aan mee wil werken. Ze hebben zelfs een website opengezet (http://openjdk.java.net/) dat als het zenuwstelsel hiervoor moet dienen.

Ik ben benieuwd wat er van Swing in de toekomst gaat komen. De volgende JDK brengt geen wereldschokkende uitbreiding van de toolkit met zich mee, maar ik denk dat het juist aan de Swing communities is om de toepasbaarheid van Swing te vergroten. Nog steeds, na al die jaren dat Swing in ontwikkeling is, denk ik dat het voor veel ontwikkelaars een ondergewaardeerde toolkit is. Het potentieel van een robuuste, goed presterende applicatie met een mondwaterende gebruikersinterface behoort zeker tot de mogelijkheden maar de mogelijkheid hiervan is niet bij iedereen bekend. Natuurlijk is Swing niet de enige speler meer op de markt als het aankomt op een web- of desktopapplicatie met een mooie grafische interface. Toch is deze toolkit veruit de meest generieke, wat ook meteen zijn kracht en tegelijk zijn zwakte vormt.

vrijdag 20 maart 2009

Wellicht Java?

Recentelijk heb ik een weblog geschreven over een bepaalde "monad", namelijk de "Maybe Monad".
Maar toen ik er bijna klaar mee was kwam ik erachter dat ik ook nog een post moest schrijven voor deze ISAAC weblog. Het artikel is een beetje te groot, en wellicht te esoterisch, om zomaar te vertalen naar het Nederlands. Daarom geef ik hier een samenvatting.

Het volledige artikel is hier te lezen.

De Maybe Monad, in de simpelste van termen, gaat over de vraag, "Wat moet een functie teruggeven als de combinatie van parameters eigenlijk tot niks uitkomt?" Om een voorbeeld te noemen, delen door nul. De meeste talen die we tegenkomen in ons werk bij ISAAC geven, in dit geval, over het algemeen een "exception", of in geval van Javascript "NaN". In feite is een exception throwen precies wat er zou moeten gebeuren, omdat delen door nul nog helemaal niet is opgelost door de wiskunde. Maar een aantal talen naast Java leveren een antwoord op deze vraag met een mechanisme dat "lichter" is dan een exception. Om dit te doen word in vrijwel alle gevallen een variatie van de Maybe Monad gebruikt. In een aantal talen is dit enorm simpel uitgedrukt, bijvoorbeeld Haskell:

data Maybe = Some a
             Nothing


Of in Scala:

trait Option {}
sealed case class Some[A](val a:A) extends Option[A] {}
sealed case object None extends Option[Any] {}


Maar dat zijn Haskell en Scala, en niet Java. Gelukkig is het (bijna) net zo simpel als in deze talen. Net zo simpel als een Pair of (simpele) Tuple class die iedereen wel eens schrijft tijdens een project. De Scala versie hierboven is eigenlijk enorm vereenvoudigd (maar is, binnen Scala helemaal functioneel te gebruiken), het heeft extra methoden, bijvoorbeeld een "getOrElse", die voor Some a terug geeft, en voor None de parameter die je meegeeft. Daarnaast is Option "Iterable", dat wil zeggen, je kan het in een for-loop gebruiken. Deze dingen zijn zeker nodig in Java, omdat Java geen Pattern Matching heeft, zoals Haskell en Scala (Haskell leeft erop!). Daarnaast zijn constant instanceof checks in je code niet veel beter dan null checks.

In Java is de Maybe Monad niet veel moeilijker in het gebruik dan het bovenstaande (code is te vinden in de post hierboven):

public Maybe integerDivide(int value, int divisor);

Het grootste voordeel is dat je de mogelijkheid dat het "fout" kan gaan expliciet gemaakt word, i.p.v. een runtime exception (zoals ArithmaticException, bij het delen door 0). Je wilt die niet zomaar krijgen in een 24/7/365 systeem alleen omdat een informatieleverancier ergens (per ongelijk) een 0 plaatst. Maar om try/catch om iedere deel operatie te zetten is ook weer te vervelend, het zelfde met iedere keer if statements om een deel operatie. Nu kan je gewoon, simpel, getOrElse aanroepen. Ik moet toegeven, in Haskell en Scala heb je het mooie Pattern Matching mechanisme, waar dit allemaal elegant word opgelost. Hoewel dit in Java iets minder elegant is, is het nogaltijd eleganter dan exceptions of velen if statements.

Daarnaast beschrijf ik hoe je de Map interface kan uitbreiden zodat deze Some teruggeeft als de key daadwerkelijk bestaat, en None teruggeeft als deze niet bestaat. Heel handig als null een goede waarde is voor een value bij een Key. Je hoeft dan niet nog een keer de key op te zoeken. En dat gebeurd ook niet in de aangepaste get, omdat er alleen Some of None waardes erin staan zal het zo zijn dat als er null terugkomt (intern) het alleen kan betekenen dat de key niet bestaat, en dan kan None teruggegeven worden.

Als laatste gaat de post over wat het nou toch is met die null, waarom ergeren we er ons toch iedere keer aan, en blijven we er toch bij terugkomen? Een van de karakteristieken van null is dat je het aan iedere type kan toewijzen, dit lijkt heel vreemd, en dat is het in feite ook. Null is een zogenaamde "Bottom Type", en is een type (in een Type System) dat (impliciet) een subtype is van alle andere types in het Type System. In Java is, bijvoorbeeld, Object een bottom type, zelfs Object subclasses Object in Java. Maar, er zit een gotcha aan, null heeft geen type. En dat is (vind ik) nou jammer, het betekend gewoon dat er allerlei special cases in de JVM en de Type System van Java zitten, alleen maar om die null waarde zonder type. Maar waarom is null nou bedacht?

Die eer komt toe aan Sir Tony Hoare, in 1965, en hij noemt het zijn "Million Dollar Mistake". Het was toendertijd zo gedaan omdat het simpeler was om te maken. Ik zal zeker de eerste zijn om te zeggen dat luiheid over het algemeen een goede karakter eigenschap is voor een programmeur, maar nu, 44 jaar later, moet zelfs ik bekennen dat er gevallen zijn waar luiheid schade berokkend. Null references zijn er een van. Het is wellicht grappig om te weten dat C++ null pointers kan hebben, maar niet null references (het zou een compiler bug zijn als dat mogelijk was!). Maar de pijn lijkt een beetje verbeterd nu er Elvis operators (zoals ze deze noemen in Groovy) komen in Java7.

En toch, ik vrees dat we voor een lange tijd niet af zijn van "null". Gelukkig hebben we gezien dat er "betere" dingen zijn in het geval "geen waarde". Dus, als je je afvraagt "wat moet ik doen als ik eigenlijk niks kan teruggeven vanuit deze functie?" Dus geen exception (tenzij het echt "exceptioneel" is) en ook geen null, want dat is een waarde, maar geen "None" terug! Maak het expliciet, de wereld zal je er dankbaar voor zijn.

zondag 8 maart 2009

Compatibility wars: nieuwe browser wars?

Het is een tijdje redelijk rustig geweest aan het browserfront. Elke maand een procentje Firefox erbij en een procentje Internet Explorer minder in de wereldwijde gebruikersstatistieken, maar dat was het dan ook wel qua spanning. Inter Explorer 6 wil (helaas) maar niet echt doodgaan in de lijstjes, hoewel er vanuit Skandinavië dappere pogingen worden gedaan om deze jaren oude security- en stadaardhel de nek om te draaien met een "Upgrade dan tenminste naar IE7"-actie. En zoals mijn CTO Front-end-collega Koen onlangs wijs sprak: "Ik heb eigenlijk liever dat IE6 gebruikers upgraden naar IE7 dan naar Firefox, want dan kunnen ze tenminste niet meer terug!". Juist! Zo erg is het met IE6. Weg ermee dus, en upgraden, hup!


Het lijkt er echter op dat we na een relatief rustige periode weer een nieuwe "oorlog der titanen" tegemoed gaan. Google kwam met het slim gethreadde hipster-browsertje Chrome (lekker snel maar niet echt een killer app naar mijn mening), maar Apple mengt zich nu ook zeer serieus in de strijd met de nieuwe Safari. En deze fraaie Safari 4-beta is 100% ACID 3-compatible! Voor de niet-zo-browser-en-web-savvy-lezer: ACID is een testsuite voor browsers om te beoordelen hoe goed een browser zich aan de webstandaarden weet te houden. IE6 scoort bijna of-the-record aan de onderkant, maar Safari 4 beta is in staat gewoon de volle 100% te scoren. Het kan dus gewoon wél! Voor webontwikkelaars is de gedachte aan een wereld met alleen maar ACID 3-compatible browsers op het internet, als een soort ultieme Red-Shoe-Diariesdroom: alles maar één keer testen, en het werkt meteen op elke PC of Mac! Oh boy oh boy! Als dat toch eens waarheid kon gaan worden!

Enfin, intussen zit Microsoft ook niet helemaal stil (IE8 komt er aan), maar helaas komt deze lang zo ver niet als Safari in de tests. IE zet wel weer een stap (en eerlijk: dit keer best een flinke), maar een echte sprong naar compatibiliteit zoals Safari en de nieuwe Opera die maken is het niet. Firefox doet zoals verwacht braaf mee in deze vooruitgangsdrift, maar lijkt wat problemen te hebben met de nieuwe Javascript-engine. Nu is een random crash en memory leak hier en daar natuurlijk ook wel traditie voor een Firefox-betaversie.

We kunnen bij ISAAC alleen maar hopen dat al die internet hatende systeembeheerders die hun medewerkers (for hell's sake) dwingen te blijven draaien op IE6 tenminste over gaan stappen naar IE8. Maar liever nog naar Safari dus, want dat lijkt een échte browser te gaan worden.

De heren van GeenStijl.nl linkten vandaag een erg interessant artikel over de "nieuwe" browser battle die in aantocht is. Een vergelijking van negen huidige en aankomende websurfapplicaties. Het is een artikel van MaximumPC.com, en brengt je in een paar minuten up-to-date met de huidige stand-van-zake op browsegebied. Klikt allen!

Zoals David Duchovny aflevering na aflevering zei: "Dear red shoes...", let this dream become reality!

maandag 2 maart 2009

DotCMS

Er is steeds meer vraag van klanten naar CMS functionaliteit, zodat ze zelf hun content kunnen beheren. Dan hoeven ze niet voor elke kleine aanpassing ISAAC te bellen, en hoeft ISAAC niet veel tijd te besteden aan kleine wijzigingen die altijd langer duren dan gepland. Er is binnen ISAAC gekozen voor DotCMS, een gebruiksvriendelijk java-based open-source systeem dat ook onder JBoss kan draaien. Dat betekent dat ISAAC hiermee makkelijk aan de slag kan, en ook extra wensen van de klant kan bewerkstelligen die buiten de huidige functionaliteit van het CMS systeem vallen.
DotCMS is op verschillende manieren te gebruiken. Zo kan het worden gebruikt om een hele website te beheren, of het kan worden gebruikt om alleen kleine delen van (bestaande) websites te CMS'en. Dus kan ISAAC op deze manier verschillende niveau's van CMS-baarheid aanbieden aan klanten.

Delen van de website in DotCMS

DotCMS is oorspronkelijk bedoeld als CMS systeem voor een hele website, of in elk geval voor webpagina's. Je maakt een template (blauwdruk) van een pagina en hergebruikt dat in je website. Maar hoe de template eruit komt te zien heb je zelf in de hand. Je kan dus een HTML template maken, maar ook een XML template. ISAAC gebruikt deze mogelijkheid om content structuren aan te maken en te beheren in DotCMS, en de content aan te bieden via XML (SOAP communicatie bijvoorbeeld). Zo kan een andere website uit DotCMS zijn content halen.
Op deze manier kan een heleboel functionaliteit van DotCMS worden gebruikt en hoef je niet de hele website in DotCMS te zetten. En je hoeft geen eigen mini-CMS te maken. Dit scheelt een hoop tijd (en geld) en biedt klanten toch al aardige CMS functionaliteit. En met handig programmeerwerk kun je voorkomen dat er meerdere calls naar DotCMS nodig zijn om meerdere soorten content op te halen, dus veel latencty heb je niet.

De hele website in DotCMS

Uiteraard kun je ook de hele website in DotCMS zetten, op die manier is alles aanpasbaar voor de klant. Daarmee krijg je alle functionaliteit die in DotCMS zit tot je beschikking. Maar waar ik iedereen voor wil behoeden is dat het gebruik van DotCMS ook nadelen met zich meebrengt... Je werkt namelijk in een bepaalde structuur en daar zit je aan vast (dat is logisch, alleen ziet de klant dat anders). Daarom moet er een duidelijk beeld worden geschept bij de klant wat er nu precies wel en niet mogelijk is in DotCMS. De details zal ik hier niet noemen, maar voor medewerkers heb ik een wiki pagina gemaakt genaamd DotCMS_Schattingen. De naam verklapt al dat er schattingen staan per onderdeel, en er staat een lijst met details over functionaliteiten. Deze kunnen je helpen bij het praten met de klant en het maken van schattingen.