blog.smart-java.nl
Ordina J-Technologies – Java Blog

Archief voor February, 2009




Spelen met Java Bluetooth

Door: Hedzer Westra, 21 February 2009

Bluetooth logo

De Bluetooth JSR-82 en de API daarbij zijn al enkele jaren oud (v1.1: 2002), maar voor mij was het een nieuwe. Hiermee kun je vanuit Java met bluetooth apparaten communiceren. Het leek me wel leuk om, al forenzend in de trein een eBook te lezen en tegelijkertijd te zien wie er allemaal elke dag met me meereist. Deze zelfde exercitie is natuurlijk ook uitstekend in de file of op vaste locaties uit te voeren…

Inmiddels hebben heel veel apparaten een bluetooth (‘bt’) module: GPS ontvangers, WiiMotes, smartphones, billboards, verkeerslichten, you name it. Elk ingeschakeld apparaat adverteert zijn nummer en meestal een (door de fabrikant of eigenaar ingestelde) naam. De leukste tot nu toe vond ik “smartföhn”, maar voornamelijk zie je de naam van de eigenaar, of het merk & type van het apparaat verschijnen. O, en laat ik vooral ‘Dennis Ordina’ niet ongenoemd laten! Welke collega met Nokia telefoon met bt adres 001A165A1686 zat op 4 februari om kwart voor zes in de intercity van Amsterdam Bijlmer naar Utrecht CS? :-) Als laatste vermelding: één telefoon had als naam het 06-nummer. Lijkt me niet handig, behalve als je wilt dat Jan en alleman je belt…

De naam Bluetooth komt overigens van de 10e-Eeuwse koning van Denemarken en Noorwegen: Harald Blåtand (niet te verwarren met Blauwbaard!). Het logo is afgeleid van de runentekens van zijn initialen.
De laatste bluetoothversie (uit 2007) is 2.1+EDR (3Mbps), en er wordt gewerkt aan een high speed variant die moderne WiFi-snelheden haalt. De radius is afhankelijk van de ‘class’ 100, 10 of 1 meter.

Begrippen

Eerst vuur ik enkele begrippen op je af uit de ‘bt’ wereld, waarna wat codevoorbeelden langskomen.

Protocol bluetooth is opgebouwd als OSI network stack van protocollen, waarvan de interessantste L2CAP (Logical Link Control and Adaptation Protocol), RFCOMM (Radio Frequency Communications) en OBEX (OBject EXchange) zijn. Het zijn op elkaar gestapelde transportprotocollen net zoals TCP en IP op elkaar gestapeld zijn. L2CAP is packet oriented en RFCOMM stream oriented. OBEX is session oriented.
Profiel interfacespecificatie; ruwweg een netwerkprotocol op applicatieniveau. Er zijn er zo’n 25 gedefinieerd; voorbeelden zijn FTP (file transfer), HID (muis/keyboard), OPP (vCards), BIP (plaatjes) en PAN (piconet). JSR-82 omvat alleen de basisprofielen GAP, SPP, SDAP, GOEP en de daarbij horende protocollen SDP (GAP+SDAP), OBEX (GOEP), RFCOMM (SPP) en L2CAP. Andere profielen moet je zelf uitprogrammeren!
Bt adres vergelijkbaar aan een Ethernet MAC-adres. Bestaat uit 12 hex digits, waarvan de eerste 6 verdeeld zijn onder de fabrikanten. Aan het adres kun je dus al zien of het bijvoorbeeld een Nokia of Motorola apparaat betreft!
Master net zoals er bij TCP/IP-verbindingen servers (daemons) zich registeren op een bekende poort en clients hiernaar connecten, is bt ook client/server georiënteerd; de server heet ‘master’ en registreert (publiceert) services. Dit vind je terug in bt UUIDs en URLs.
UUID uniek nummer om een service (gedefinieerd in een profiel) te identificeren, vergelijkbaar aan een server IP port number. In 3 lengtes: 4, 8 of 32 hex digits. Er bestaat een simpele conversie om 4/8-digit UUID’s naar volledige lengte te converteren: concateneren met het vaste nummer 00001000800000805F9B34FB. Enkele voorbeeldwaarden: OBEX File Transfer = 0×1106, Human Interface Device Profile (WiiMote!) = 0×1124.
BCC Bluetooth Control Centre; een GUI om je device, services & security te configureren, en te zoeken naar & pairen met andere devices. Meegeleverd met je bt driver.
URLs je maakt connecties met behulp van URLs in het bekende formaat. Server URLs bevatten altijd “localhost”, de service UUID en eventueel parameters zoals een naam. Client URLs bevatten het remote bt adres, het kanaal- of PSM [Protocol Service Multiplexer] nummer – vergelijkbaar met een client IP port number; is niet hetzelfde als een service UUID – en eventueel (security) parameters. Enkele voorbeelden:
o OBEX/GOEP
Server btgoep://localhost:ed495afe28ed11da94d900e08161165f
Client btgoep://00A3920B2C22:12
o RFCOMM/SPP
Server btspp://localhost:;name=Sample SPP Server
Client btspp://0050CD00321B:3;authenticate={true|false}; authorize={true|false};encrypt={true|false}
o L2CAP
Client btl2cap://0050CD00321B:1003; ReceiveMTU=512;TransmitMTU=512
Piconet mininetwerk van maximaal 8 bt devices – meer verbindingen ondersteunt bluetooth niet. Een netwerk van meerdere aan elkaar gekoppelde piconets heet een scatternet.
Service class elk bt device kan met zijn service class aangeven welke service types hij ondersteunt (bijv. positioning, networking of audio) en van welk (sub)type hij is (bijv. Computer/Laptop of Peripheral/Joystick).
Discovery scannen naar devices en/of services. Na discovery levert JSR-82 je URLs zodat je die niet zelf hoeft op te bouwen. Een bt device kan altijd (‘global’/’general’) discoverable zijn (GIAC), een beperkte tijd (‘limited’ – LIAC) of helemaal niet. Dit poor-mans beveiligingsmechanisme is bekend van WiFi routers. Ook daar is de fabrieksinstelling meestal niet de veiligste… Discovery is niet erg snel; een complete sweep van devices & hun services duurt afhankelijk van het aantal devices in bereik één tot meerdere minuten, dit onder andere omdat er geen parallelle service discoveries kunnen draaien.
Service record bij discovery van een service ontvang je een lijst van attributen met onder anderen een leesbare naam en kanaal (RFCOMM&OBEX)- of PSM (L2CAP) nummer. Helaas vullen niet alle bt devices dit service record exact volgens de specs.
Pairing pas nadat apparaten aan elkaar bekend zijn gemaakt middels een PIN-code (meestal 0000…) kan communicatie gestart worden. Helaas voor mijn tagger kan dit alleen via de BCC; de JSR-82 API voorziet er niet in om een PIN-code door te geven. Bij pairing wordt overigens ook een gedeelde 128b sleutel afgesproken, die daarna gebruikt wordt als autorisatie en/of encryptie aangezet worden. Dat laatste kan dan wel weer vanuit Java. Discovery is overigens wel mogelijk zonder te pairen; mijn tagger kan van elk device dat in bereik is en in bluetooth discovery mode staat (hetgeen bijna elke telefoon is, vanuit de winkel) de volgende attributen uitvragen: bt adres, naam, service class, services inclusief naam, UUID en URL. Als een pairing wel bestaat (in JSR-82 termen: het device is ‘trusted’), is het mogelijk om een connectie op te bouwen, bijv. simpelweg om de pingtijd te meten.

Codevoorbeelden

De betrokken Java packages zijn: javax.bluetooth, javax.obex en javax.microedition.io.
Wat betreft dat laatste package: JSR-82 heeft veel raakvlakken met J2ME (termen in het verlengde hiervan: MIDP, CLDC en CDC), wat logisch is omdat bluetooth in 1998 door Nokia bedacht is als draadloze communicatie van mobieltjes naar andere apparaten. Mocht je iets met J2ME & bt willen doen (laat me je resultaten weten!): telefoons kunnen zelf ook JSR-82 implementeren, maar niet alle telefoons met bt & Java doen dat! Zie de bluecove Wiki voor een lijst.

De API is vrij klein. De belangrijkste klassen zijn DiscoveryAgent, LocalDevice en RemoteDevice.

Twee problemen die ik ben tegengekomen met deze API:
1. Een afgrijselijke klasse is DataElement. Dit is een wrapper voor diverse soorten datatypes. Je zult er helaas mee moeten leven.
2. Als je alleen het bt adres van een device weet, dan moet je eerst discoveren. Je kunt namelijk niet op basis van dit adres een RemoteDevice (laten) instantiëren. Maar als je een URL kent kun je wel meteen connecten! Vreemd…

Nu volgen enkele zeer kleine & korte codevoorbeelden – check voor enkele compleet werkende applicaties de Eclipse workspace op de Ordina Wiki. (Helaas zijn de syntax highlighting & tabs verloren gegaan bij kopiëren vanuit Word naar WordPress…)

// setup: get local device & discovery agent
LocalDevice localDevice = LocalDevice.getLocalDevice();
DiscoveryAgent discoveryAgent = localDevice.getDiscoveryAgent();

// start global device inquiry
MyDiscoveryListener discoveryListener = new MyDiscoveryListener();
boolean limited = false;
boolean started = discoveryAgent.startInquiry(
limited ? DiscoveryAgent.LIAC : DiscoveryAgent.GIAC,
discoveryListener);

// retrieve name of first remote device in list
RemoteDevice remoteDevice = discoveryListener.getDiscoveredDevices().get(0).getRemoteDevice();
String deviceName = remoteDevice.getFriendlyName(true);

// search for services using RFCOMM on the first remote device
UUID[] uuids = new UUID[]{new UUID(BluetoothConstants.PROTOCOL_RFCOMM)};
int transId = discoveryAgent.searchServices(null, uuids, remoteDevice,
discoveryListener);

// retrieve a connection URL using the first service record
ServiceRecord record = discoveryListener.getServiceRecords().get(transId)[0];
String url = record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);

// open L2CAP, RFCOMM & OBEX connections
L2CAPConnection l2capConnection = (L2CAPConnection) Connector.open(url);

StreamConnection rfcommConnection = (StreamConnection) Connector.open(url);

ClientSession obexConnection = (ClientSession) Connector.open(url);
HeaderSet hsConnectReply = obexConnection.connect(null);
if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
// 196 = not found, 204 = precon failed, 160 = ok
LOG.error(“expected OBEX_HTTP_OK but got ” + hsConnectReply.getResponseCode());
}

Hoe service registratie werkt (dit is: opzetten van een server connectie die wacht op clients) kun je terugvinden in de Eclipse workspace.

OBEX – OBject EXchange

OBEX is ‘geleend’ van de IrDa (infrarood) wereld, vandaar dat de API een eigen package javax.obex heeft. Binnen bt werkt OBEX bovenop RFCOMM, maar OBEX ondersteunt ook IrDa en TCP/IP als transportlaag.

Ondersteunde diensten zijn o.a. FTP (phone2PC), Object Push (phone2phone – zogezegd gebruikt bij toothing, Sync, basic imaging en basic printing.

Het protocol doet denken aan HTTP. Herkenbare concepten zijn:
• Headers 12 gedefinieerde parameters, o.a. name, type en length
• Sessions op basis van connectie ID
• Content types text/vcard, x-obex/folder-listing, etc.
• Commands CONNECT, PUT, GET, SETPATH, ABORT, CREATE-EMPTY, PUT-DELETE en DISCONNECT
• Error codes OBEX_HTTP_OK, OBEX_HTTP_NOT_FOUND, etc.

Voorbeelden van uit te wisselen data zijn: vCard, vCalendar, vMessage, vNotes en platte bestanden.

De belangrijkste 4 klassen/interfaces en hun supertypes zijn:
• ClientSession > Connection
• HeaderSet
• Operation > ContentConnection > StreamConnection > OutputConnection & InputConnection > Connection
• SessionNotifier > Connection

JSR-82 implementaties & bt stacks

Bluecove is momenteel de enige actief onderhouden, bruikbare en gratis JSR-82 implementatie, maar werkt gelukkig redelijk goed. Bluecove heeft wel een bluetooth stack nodig. Voor Windows wordt widcomm aangeraden en BlueSoleil ten zeerste afgeraden – dit kan ik beamen! De bluetooth stack wordt meegeleverd met je chipset, dus kiezen kun je niet. Gelukkig bevat mijn Ordina laptop (HP Compaq 6910p) een widcomm ingebouwd. Wel eerst even een service pack van 100MB installeren! Voordat ik dat deed werd de widcomm niet herkend en ben ik met een USB bt stikkie van cygnet aan het klooien geweest. Helaas zat daar BlueSoleil bij en dat ging niet erg lekker.

Op Linux kun je gebruik maken van de BlueZ stack. Ik heb ‘m niet geprobeerd – laat me je ervaringen weten!

Een mogelijk client programma is Nokia PC Suite, die bijvoorbeeld. een remote file browser biedt. Helaas installeert Nokia zoveel dingen achter je rug om (koppelt onder andere de JAR extensie aan een Nokia application installer!) dat ik deze afraad.

Overigens werkt ook de combinatie widcomm & bluecove niet vlekkeloos. Enkele keren heb ik een JVM crash gehad, een vastlopende BT stack (een volledige herstart helpt, maar soms is killen van BTStackServer.exe voldoende), een BCC die mijn connecties afpakte (alleen een unpair/pair-actie verhelpt dit), et cetera. Als je de documentatie van bluecove mag geloven, ligt dit eerder aan de slechte staat van bluetooth stacks, danwel aan een mismatch tussen stacks en JSR-82, dan aan bluecove zelf. Toch krijg ik een beetje een déjà-vu met JMF en Java Serial: ook dit zijn Java extensies waarvoor eigenlijk nooit een goede (reference) implementatie is gekomen, en door Sun een beetje aan hun lot lijken te zijn overgelaten.

Documentatie

Er bestaat een bluetooth SIG die alle specs publiceert; onder andere die van alle profielen. Helaas moet je voor de meest informatie lid zijn, en dat kunnen alleen betalende bedrijven of universiteiten. Ik heb ze gecontacteerd voor een simpele lijst met standaard UUID nummers, en kreeg pas na lang aandringen antwoord – natuurlijk pas nadat ik mijn code af had. De online documentatie & tutorials die ik wél gevonden heb is helaas vaak slecht, oud, weinig diepgaand en lastig te vinden – ik heb hier en daar door open source code moeten snuffelen voor ontbrekende informatie (zoals voornoemde UUID nummers).

Voor mijn source code, verwijzingen naar boeken, meer technische informatie, een lijst van geregistreerde UUIDs, attributen en service classes, en extra URLs verwijs ik je naar de Ordina Wiki pagina die ik hiervoor opgezet heb.

Mocht je zelf ook aan de gang gaan met Java bluetooth, dan hoor ik graag van je terug wat je resultaten zijn. Codebijdragen zijn natuurlijk welkom op de Wiki!

Hedzer Westra

Hedzer Westra




Domain Driven Design in de Referentie Architectuur.

Door: Pieter van Boxtel, 19 February 2009

In de huidige versie van de Referentie Architectuur hebben we verklaard aanhanger te zijn van Domain Driven Design. We hebben domein objecten gedefinieerd, maar wat doen we nu eigenlijk met het gedachtengoed van Evans? Een van de doelen voor de volgende versie is te kijken of we de patterns van DDD een plekje kunnen geven. Hieronder een poging daartoe, waarbij ik niet al te veel beschrijving of uitleg van de patterns geef. Voor een goede uitleg van de patterns is een niet te overtreffen bron, en dat is het boek van Evans.

Evans beschijft eigenlijk twee soorten patterns. De eerste soort geeft een onderscheid in typen objecten en methoden. Deze patterns zijn concreet terug te zien in een domein model. Dit zijn de patterns waar we echt iets mee kunnen in de referentie architectuur. De tweede soort zijn eerder proces patterns. Deze beschrijven wat abstractere doelen en wegen naar deze doelen. Deze patterns zijn moeilijk concreet te maken in een referentie architectuur en ze komen hier verder niet meer aan bod.

Kern van een DDD domein model zijn Entities (89) en Value Objects (97). Dit zijn de klassieke OO objecten met een toestand en gedrag. Entities zijn objecten met een “identiteit”. Ze zijn niet uitwisselbaar. Ze kunnen gedurende hun levensduur veranderen, maar ze blijven uniek. Een persoon object is in de regel een Entity. Een persoon wordt ouder, zijn uiterlijk verandert, allerlei attributen wijzigen, maar een persoon blijft dezelfde identiteit. Value Objects daarentegen zijn wel uitwisselbaar. In een klantencontactsysteem is een adres niets meer dan een verzameling attributen. Een adres object kan hergebruikt worden, maar dat hoeft niet. Het maakt niet uit als in het systeem twee adres objecten geïnstantieerd zijn met hetzelfde adres. En als een persoon en zijn adres uit memory verdwijnen, dan is het wanneer de persoon opnieuw opgevraagd wordt niet belangrijk dat hetzelfde adres object teruggevonden wordt. (Voor een kadastraal systeem gaat deze redenatie uiteraard niet op…)

Onderscheid tussen Entities en Value Objects is waardevol bij het ontwerp van een applicatie. We kunnen andere ontwerpregels op deze typen objecten loslaten. Zo is het een goed idee om Value Objects immutable te maken. Wanneer een attribuut dient te wijzigen vervangen we het object gewoon door een nieuwe instantie. Fowler definieerde het onderscheid tussen Entities en Value Objects al in Patterns of Enterprise Application Architecture. Hij lijkt Value Objects echter te suggereren voor algemene, herbruikbare zaken, zoals Money. Evans gebruikt het onderscheid structureler door elk “klassiek” domein object in een van beide hokjes te duwen. Bijvoorbeeld in een facturatie systeem kunnen we facturen modelleren als Entities en factuurregels als Value Objects.

Ook geeft Evans enkele richtlijnen voor het opstellen van Entities en Value Objects:

  • Gebruik Intention-Revealing Interfaces (246), waarbij namen van klassen en methoden hun effect en doel beschrijven.
  • Gebruik Side-Effect-Free Functions (250), factor deze uit in Value Objects en maak er Closed Operations (268) van.
  • Maak daarentegen van Entity methodes die de state wijzigen commands die geen domein klassen teruggeven. Gebruik Assertions (255) om post-condities en invarianten van deze methodes te controleren.

Services (104) zijn objecten met enkel gedrag. Ze bevatten methoden die geen logische plek hebben in een Entity of Value Object. De naam ‘Service’ is enigszins verwarrend aangezien de term ’service’ in de Referentie Architectuur en andere architecturen in een andere context gebruikt wordt. Een betere naam is wellicht ‘Domain Service’.

Entities en Value Objects zijn de objecten in het domein model die gepersisteerd worden. Factories (136) en Repositories (147) zijn de domein objecten die voor persistentie verantwoordelijk zijn. Factories creëren domein objecten en Repositories bieden zoek-ingangen. Een Factory is in feite geen afzonderlijk type object. Een Factory wordt gerealiseerd door middel van een Factory Method (GoF) op een Entity of op een al dan niet speciaal voor het doel gecreëerde Service. Door vanuit de Factory Method te delegeren naar een ‘add’ methode op een Repository bewerkstelligen we dat database logica in één type domeinobject gecentreerd wordt.

De eenheid voor persistentie is een Aggregate (125). Dit is verzameling van een of meerdere entities en value objects, waarbij één entity, de root, als aanspreekpunt fungeert. Alle niet-root objecten in de aggregate staan uitsluitend ter dienste van de root en objecten buiten de aggregate hebben uitsluitend relaties naar de aggregate root.

Verder kunnen domeinobjecten gegroepeerd worden in Modules (109), om zodoende structuur te creëren in het domeinmodel. Modules of Packages zijn standaard concepten in OO programmeertalen en modelleertechnieken.

Een Specification (224) tenslotte is een eenvoudig Value Object dat een (of meerdere) business rule controleert voor een ander object. Specifications zijn gebaseerd op predicatenlogica waardoor ze als logische condities zijn te combineren tot complexere business rules. Een Specification kan drie doelen hebben:

  1. Validatie van een business rule op een object. Een toepassing hiervan is de manier waarop Mod4J met business rules in de domein DSL omgaat.
  2. Een selectie criterium specificeren om een object uit een selectie te selecteren. Een toepassing hiervan is gebruik van een Specification als parameter voor een Repository.
  3. Bouw van een nieuw object specificeren.

Onderstaand plaatje toont bovenstaande patterns en hun relaties:

De hierboven genoemde patterns kunnen we zonder al te grote gevolgen in de referentie architectuur opnemen ter vervanging van / uitbreiding op de huidige typen business componenten. De vertaling gaat dan als volgt:

  • De huidige Referentie Architectuur kent Business Processen, welke vergelijkbaar lijken met Domain Services. Business Processen zijn echter geen onderdeel van het domein model, ze worden niet aangeroepen door domein objecten. Verder stelt de Referentie Architectuur dat elke aanroep van een domein object via een business process gaat. In feite hebben we met deze Business Processen een extra “laagje” gecreëerd dat redundant is, aangezien erboven zich een verplichte servicelaag bevindt. Niets let ons om dat laagje te schrappen en domain services alleen te definieren als ze een toegevoegde waarde hebben.
  • De domein objecten zoals we ze nu kennen kunnen we onderverdelen in Entities en Value Objects.
  • Aggregates worden nu wel genoemd in de implementation view als eenheid van persistentie, maar ze worden niet expliciet onderkend als modelleereenheid in de logische view.
  • Specifications zijn nieuw ten opzichte van de referentie architectuur, hoewel Mod4J ze wel al toepast voor business rules.
  • Repositories zitten nu in een afzonderlijke laag, de datalaag, en heten Data Access Logic component. Echter, zoals ik in een vorige blog betoogde is dat niet terecht en horen ze in de domeinlaag thuis.
  • Volgens diezelfde blog zijn de Service Agents en Data Service Agents zoals we ze nu kennen dezelfde dingen en kunnen we ze onderbrengen in een (nieuwe) laag, de Integratielaag.

Mijn conclusie is dat we door toepassing van de DDD patterns de referentie architectuur consistenter en begrijpelijker kunnen maken. In het ontwerp van een applicatie komt meer structuur, terwijl het resultaat, de implementatie, nagenoeg niet wijzigt ten opzichte van de huidige referentie architectuur. Bijkomend voordeel van toepassing van DDD is dat we voor de educatie van de architectuur kunnen verwijzen naar het boek “Domain Driven Design” van Evans.




Wat is er nieuw aan Model-Driven Development?

Door: Eric Jan Malotaux, 13 February 2009

Toen de Object Management Group (OMG) in 2001 de Model Driven Architecture (MDA) introduceerde, veroorzaakte dat een golf van optimisme onder de relatief weinigen die zich nog met code-generatie bezig hielden. Eindelijk een standaard modelleertaal(UML), en dus uitwisseling van modellen tussen tools van verschillende leveranciers. Inmiddels is het enthousiasme voor het pure MDA vrijwel helemaal weggeëbt. Voornamelijk doordat UML nou niet ideaal bleek om behalve als modelleertaal, tegelijkertijd ook te dienen als basis voor het genereren van code. Te ingewikkeld, te groot, niet precies genoeg. En die standaardisatie bleek ook meer theorie dan praktijk. Om bruikbare code uit UML te kunnen genereren moest er nogal wat aan UML gesleuteld worden, dan deed iedere leverancier weer anders. Dus zeg maar dag tegen overdraagbare modellen!

Maar de laatste twee jaar komen de ideeën in een net even andere gedaante weer terug: nu op basis van Domain-Specific Languages (DSL’s). DSL’s zijn bezig in snel tempo enorm populair te worden. Overal wordt er mee geëxperimenteerd, en de conferenties over MDD schieten als paddestoelen uit de grond.  Hiervoor zijn verschillende oorzaken: (1)  DSL’s zijn veel kleiner en hanteerbaarder dan UML. (2) Het opkomen van tools als Microsoft DSL Tools, openArchitectureWare(oAW), en vooral xText, die het zelf maken van DSL’s binnen het bereik van “gewone” ontwikkelaars hebben gebracht. Grappig genoeg zijn al deze tools uiteindelijk in gebaseerd op één of andere gedaante van de Meta Object Facility (MOF), de kern van de MDA. Dit meta-metamodel standaardiseert het ontwikkelen van nieuwe metamodellen, en daarmee van nieuwe (modelleer)talen.  (3) DSL’s komen als geroepen. De complexiteit van de gemiddelde JEE applicatie neemt zo snel toe dat weinig ontwikkelaars het kunnen bijhouden. Aan de achterkant van een applicatie – de kant het dichtst bij de database – valt het nog wel mee: Hibernate is een blijvertje gebleken, al of niet in de incarnatie als JPA-implementatie. En ook het Spring-framework blijft een rots in de branding. Alhoewel, wat is nou beter: configuratie met XML bestanden of met annotaties? En Spring groeit ook als kool: wat moeten we met OSGi en Spring Integration. Maar aan de voorkant – de kant het dichtst bij de gebruiker – is de grote lijn helemaal zoek. Een jaar of acht geleden was Struts éénoog koning, maar nu moet je voor iedere applicatie kiezen tussen JSF, Wicket, GWT, Spring MVC of Webflow, of toch maar weer een Rich Client. En dan vergeten we voor het gemak even de technologieën die tussendoor nog even populair zijn geweest, zoals XML/XSLT. Het valt niet meer te behappen voor een gewoon mens, die ’s-avonds ook nog wel eens een film wil zien in plaats van een tutorial (als dat er is tenminste) van weer een nieuw framework door te werken.

Model-driven Development op basis van DSL’s belooft een oplossing voor deze chaos. We ontwerpen een DSL voor het domein waarvoor we een applicatie maken, en een generator waar we de complexiteit in kunnen verstoppen. Daarvoor heb je dus nog wel een nerd nodig die al die ontwikkelingen wèl heeft kunnen bijbenen, maar de rest hoeft alleen maar de DSL te leren. En de nerd kan zich helemaal uitleven in de codegenerator, dus iedereen tevreden. Zou je zeggen.

Nou hebben we natuurlijk al vaker nieuwe ontwikkelingen meegemaakt die veel beloofden maar uiteindelijk teleurstelden. Object-oriëntatie, aspect-oriëntatie, agile development, test-driven development, whatever-driven-development, frameworks. Dus zo zal het met MDD ook wel weer gaan.  Toch hebben die nieuwe ontwikkelingen wel blijvende vooruitgang gebracht, alleen minder revolutionair dat we hadden gehoopt. Dus is de vraag, waarin ligt de echte verbetering van MDD, en waarin zal het tegenvallen.

Het ontwerpen van een DSL is moeilijk. Niet alleen de taal zelf, maar ook de benodigde tools om er een beetje lekker mee te kunnen werken. Dus zou het prettig zijn ‘m te kunnen hergebruiken. Daarom wordt vaak de applicatie architectuur als domein gekozen wordt in plaats van het domein van de gebruiker van de applicatie. Bij mod4j (http://www.mod4j.org/projectsite) bijvoorbeeld is dat gedaan. Maar de visie van de OMG – scheiden van pure business functionaliteit van implementatiedetails – wordt maar gedeeltelijk bereikt.  Want we moeten de applicatie specificeren in termen van de applicatie architectuur in plaats van concepten die betekenis hebben voor de klant. We maken wel modellen, maar sinds het verschijnen van tekst-gebaseerde tools als xText kunnen we die net zo goed maken in tekstuele vorm als in diagram vorm.  Wat is dan nog het verschil tussen een model en een programma?  Eigenlijk geen.  Vandaar dat Anneke Kleppe in haar nieuwe boek “Software Language Engineering: Creating Domain-Specific Languages Using Metamodels” de term “mogram” introduceert.

Wat is dan eigenlijk nieuw? Eenvoudig dit: met een DSL werkt een programmeur op een hoger abstractieniveau. Hij heeft met minder concepten te maken dan met puur Java. Dat resulteert in veel compactere code. Bij mod4j bijvoorbeeld worden er per regel DSL-code bijna 25 regels Java- en XML-code gegenereerd. Volgens Frederick Brooke in zijn boek “The Mythical Man Month” is de productiviteit van een programmeur constant in termen van het aantal statements per tijdseenheid. Mod4j is nog niet in de praktijk beproefd, dus wat de winst echt is moet nog blijken. Hoopgevend is het in elk geval wel.