Follow Us on Twitter

Rapid Enterprise Development met Forge en Roo

November 2012 - Over Rapid Application Development, kortweg RAD, is al een hoop geschreven. RAD stelt een ontwikkelaar in staat om bijvoorbeeld:

  • snel een prototype te ontwikkelen voor een gebruikersdemo;
  • een stabiele code-basis neer te zetten waarbinnen vervolgens de bedrijfsspecifieke eisen, die niet gegenereerd kunnen worden, handmatig uitgeprogrammeerd kunnen worden;
  • standaard constructies (denk aan JPA en DAO klassen) te laten genereren. Deze hoeven dus niet meer handmatig geprogrammeerd te worden. Dit zorgt voor meer consistente en over het algemeen minder foutgevoelige code.

Voor Java Enterprise ontwikkeling zijn recentelijk een aantal frameworks ontstaan die RAD mogelijk maken. De twee grote spelers SpringSource en JBoss bieden beiden een RAD-framework aan, Roo resp. Forge. Spring Roo is gebaseerd op het populaire Spring framework, terwijl Jboss Forge "standaard" JEE genereert. Tijd om beide frameworks in dit Whitebook eens uit te lichten.

Suites

Beide frameworks zijn los te installeren, waarna ze via de commandline zijn te bedienen, maar beide zijn ook geïntegreerd in de -op Eclipse gebaseerde– IDE's die beide spelers aanbieden.

De IDE van SpringSource heet de Spring Tool Suite (STS). Ten tijde van dit Whitebook is versie 3.1.0 beschikbaar als gratis download. Deze maakt gebruik van Spring Roo 1.2.2 GA.

De IDE van JBoss, JBoss Developer Studio, momenteel versie 5.0.1 GA, maakt gebruik van JBoss Forge 1.0.5. Ook deze IDE is gratis te downloaden, maar vereist wel dat je eerst een account aanmaakt.

In dit Whitebook zullen beide tools vanuit hun respectievelijke IDE's geopereerd worden.

CRUD-applicatie

Om een beeld te krijgen bij beide frameworks zal in dit Whitebook een simple CRUD-applicatie gegenereerd worden. Hierbij wordt bij beide frameworks hetzelfde stramien doorlopen.

  1. Allereerst wordt een nieuw project aangemaakt, waarbij o.a. de Maven pom.xml file wordt ingevuld;
  2. JPA setup, waarbij de dependencies worden bijgewerkt en de persistence.xml file wordt ingevuld;
  3. Nu kunnen de domein/entity objecten worden aangemaakt. Relaties tussen objecten worden hierbij ondersteund alsmede constraints op de individuele velden (Bean Validation);
  4. UI setup: afhankelijk van de gebruikte techniek voor de UI laag worden hier de dependencies bijgewerkt, de diverse descriptor files (o.a. web.xml) ingevuld en allerlei template files toegevoegd aan het project;
  5. Tenslotte kunnen aan de hand van de domeinobjecten de CRUD-schermen gegenereerd worden. Hierbij wordt ook de DAO- en controller-code ingevuld.

Schema CRUD genereren
Figuur 1: schematische weergave CRUD-generatie.

Forge

De integratie van Forge gaat momenteel niet verder dan het aanbieden van een Console Window binnen de IDE waarmee, analoog aan werken via de commandline, de commando's ingetikt kunnen worden (zie figuur 2). Toch werkt dit bijzonder prettig. Als je de basis commando's eenmaal machtig bent, wijst Forge zich vanzelf. Erg handig is de Tab toets die commando's automatisch aanvult, danwel een lijst met suggesties oplepelt. Voor een uitgebreide lijst met commando's kan het list-commands commando worden gebruikt.

Forge Console
Figuur 2: Forge Console

Analoog aan de stappen beschreven hier, bouwen we aan de hand van een paar commando's een werkende CRUD-applicatie. Naast de JBoss IDE is alleen een JBoss Server vereist. De Community Edition is hier te downloaden. Ten tijde van dit Whitebook is versie 7.1.1. Final voorhanden.

Na het opstarten van de Forge Console kan een nieuw project aangemaakt worden:

[no project] jboss-workspace $ new-project --named forge_red --topLevelPackage nl.whitehorses.red.forge

Dit commando creëert een nieuw Maven-project met de naam forge_red. Het wordt ter plekke toegevoegd aan de IDE en bevat naast een pom.xml file, enkel een forge.xml file voor Forge-specifieke zaken.

[forge_red] forge_red $ persistence setup --provider HIBERNATE --container JBOSS_AS7

Hiermee wordt alle JPA-setup geregeld met Hibernate als JPA-implementatie. De pom.xml wordt bijgewerkt met de juiste Hibernate/JPA dependencies. Daarnaast wordt de persistence.xml file aan het project toegevoegd met de juiste Hibernate settings en de ExampleDS datasource. Dit is de default datasource in de JBoss Server waarmee een embedded HSQL database gebruikt kan worden. M.b.v. de jndiDataSource flag kan indien gewenst, met een JNDI datasource worden gekoppeld.

Nadat de persistence setup is ingeregeld, kunnen de domein/entity objecten gecreëerd worden.

[forge_red] forge_red $ entity --named Employee

Hiermee wordt een Employee @Entity klasse aan het project toegevoegd. Naar goed gebruik zijn een @Id en @Version field toegevoegd. Ook zijn de toString(), hashCode() en equals() methode overschreven.

Vervolgens kunnen nieuwe velden worden toegevoegd:

[forge_red] Employee.java $ field string --named lastName

[forge_red] Employee.java $ field number --named salary

Zoals te zien is, worden beide velden in de context van de Employee klasse toegevoegd. Indien net, zoals in ons voorbeeld, een entity is gecreëerd, staat deze context al goed, anders kan m.b.v. het cd commando (analoog aan directory's navigeren) naar de klasse genavigeerd worden voor de juiste context. Bij het salary veld moet nog een type worden opgegeven, bv. java.math.BigDecimal.

Na het toevoegen van een veld, is te zien dat de Employee POJO is bijgewerkt met een @Column variabele en getter en setter methoden.

De model laag van de CRUD applicatie is nu voltooid. Tijd voor de view laag. Dit vereist 2 stappen. Allereerst moeten de nodige dependencies in de pom.xml worden toegevoegd voor JSF.

[forge_red] forge_red $ scaffold setup

Hiermee wordt de packaging omgezet van jar naar war. Daarnaast worden een aantal facelets (index.xhtml, error.xhtml en pageTemplate.xhtml) toegevoegd en worden de faces-config.xml (voor JSF), beans.xml (voor CDI) en web.xml descriptor files toegevoegd. De pageTemplate.xhtml is voor een groot deel verantwoordelijk voor de look and feel van de gegenereerde pagina's. Deze kan uiteraard aangepast worden naar de eigen huisstijl.

Tenslotte dienen alleen nog de CRUD pagina's voor het domein object gegenereerd te worden.

[forge_red] forge_red $ scaffold from-entity Employee

Dit creëert een search.xhtml, view.xhtml en create.xhtml facelet. Binnen de schermen zijn velden voor foutboodschappen aanwezig. De gegenereerde schermen zijn ook via een WYSIWYG-editor te bekijken.

Tevens wordt de EmployeeBean klasse gegenereerd. Dit is de lijm tussen het domein-object, de facelets en de persistency provider. De EmployeeBean is een stateful EJB3 session bean en doet naast JSF backing bean dienst als DAO voor de onderliggende Employee-tabel. Ook de controller-logica (o.a. pagina-navigatie) is opgenomen in deze bean. Dit alles wordt mede mogelijk gemaakt door de in JEE6 geïntroduceerde CDI annotaties.

Dit zijn alle stappen. Het project kan nu gedeployed worden naar de JBoss server (vanuit de IDE: Run As > Run on Server). Hierna wordt de applicatie in de IDE getoond (zie figuur 3, 4 en 5).

Welkom-scherm Forge
Figuur 3: welkom-scherm gegenereerde applicatie

Zoek Employee
Figuur 4: search.xhtml: zoekscherm

Creeer Employee
Figuur 5: creëer een nieuwe Employee

Overige mogelijkheden Forge

In een paar korte stappen is een werkende CRUD applicatie opgetuigd. Forge maakt het mogelijk om de applicatie nog verder te verfijnen. Zo is het o.a. mogelijk om:

  • Relaties tussen @Entity klassen toe te voegen
    [forge_red] Employee.java $ field manyToOne --named department
    
  • Bean Validation aan de JPA entity-klasse toe te voegen
    [forge_red] Employee.java $ validation setup
    
    [forge_red] Employee.java $ constraint NotNull --onProperty lastName
    
  • Te kiezen uit diverse databases, JPA-providers en applicatie-servers
    [forge_red] forge_red $ persistence setup --provider ECLIPSELINK --database MYSQL5_INNODB --container GLASSFISH_3
    
  • soap/rest setup toe te voegen (hiermee worden o.a. de nodige dependencies toegevoegd aan de pom.xml file)
    [forge_red] forge_red $ soap setup
    
    [forge_red] forge_red $ rest setup
    

Via de installatie van Forge plugins komen extra commando's beschikbaar. Om het veelgebruikte logging framework slf4j/log4j toe te voegen aan een project, dient eerst de slf4j-plugin geïnstalleerd te worden, waarna de dependencies en log4j.xml descriptor toegevoegd worden middels een setup commando:

[forge_red] forge_red $ forge install-plugin slf4j

[forge_red] forge_red $ slf4j setup

De extra opties zijn legio binnen Forge. Het is te verwachten dat dit in de toekomst nog verder uitgebreid wordt. Denk hierbij bv. aan uitgebreide SOAP-support met de mogelijkheid om aan de hand van een WSDL-file JAXB-klassen te genereren, of aan support voor NoSQL databases.

Spring Roo

Ook voor Roo is online een tutorial beschikbaar voor het bouwen van een CRUD-applicatie.

De integratie met de IDE is iets verder uitgewerkt dan bij Forge, maar werkt over het algemeen vrijwel hetzelfde. Via File > New > Spring Roo project wordt een nieuw project aangemaakt.

Nieuw Roo project
Figuur 6: Nieuw Roo Project

Het nieuwe project wordt geopend in de IDE. De Maven pom.xml en Spring context file applicationContext.xml worden geïnitialiseerd en een default log4j.properties file wordt toegevoegd.

In de pom.xml zijn standaard plugins voor Tomcat en Jetty opgenomen.

Bij het creëren van een nieuw project wordt tevens de zgn. Roo Shell gestart. De Roo Shell biedt grofweg dezelfde functionaliteit als de Forge console. De hint en help commando's zorgen voor uitgebreide informatie m.b.t. de commando's en m.b.v. de Ctrl+space combinatie kunnen commando's automatisch aangevuld worden.

Roo Shell
Figuur 7: Roo Shell

Allereerst wordt weer de persistence ingeregeld. Voor het gemak wordt gewerkt met een in memory database, maar er kan ook voor MySQL of Oracle worden gekozen.

roo$ jpa setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY

De pom.xml wordt bijgewerkt met de benodigde dependencies voor Hibernate/JPA en een geconfigureerde persistence.xml file wordt toegevoegd aan het project. In tegenstelling tot het Forge-project wordt hier niet via een JNDI-naam gewerkt, waardoor ook een database.properties file wordt toegevoegd aan het project. Deze bevat database-driver- en connectie-informatie. Tenslotte wordt ook de context file bijgewerkt met JPA-, JTA- en database-setup. Roo biedt ook al de mogelijkheid om gebruik te maken van MongoDB als persistentielaag, via het mongo setup commando.

Nu kunnen de domein-objecten aangemaakt worden.

roo$ entity jpa --class nl.whitehorses.red.roo.domain.Employee

Dit commando creëert een schone Employee POJO-klasse tezamen met een aantal Aspect4J files.

Roo maakt veelvuldig gebruik van Aspect4J. De Employee klasse wordt via een aantal aj-files verrijkt met functionaliteit. De belangrijkste zijn

  • Employee_Roo_Jpa_Entity.aj: deze file bevat de ORM informatie en maakt van de Employee pojo een @Entity bean;
  • Employee_Roo_Jpa_ActiveRecord.aj: Deze file bevat de persistence operaties en maakt van de Employee POJO een DAO.

Via de --testAutomatically flag kan tevens een aantal testklassen gegenereerd worden (ook weer met aj-files). Analoog aan de Forge console wordt binnen de Roo Shell nu ook de context omgezet naar de Employee klasse. Een mooi moment om velden toe te voegen.

~.domain.Employee roo$ field string --fieldName lastName –notNull

~.domain.Employee roo$ field number --fieldName salary --type java.math.BigDecimal

Constraints zijn, zoals te zien in het voorbeeld, afwijkend van Forge rechtstreeks toe te voegen bij het aanmaken van een veld. In beide gevallen wordt het nieuwe veld toegevoegd aan de Employee klasse en de getters en setters aan de Employee_Roo_JavaBean.aj file. Dit alles maakt ook weer dat de Employee-klasse heel dun blijft met alleen instance-variabelen en er bijna uitziet als een Groovy klasse.

De model laag is nu compleet en de view laag kan opgezet worden. Aangezien we met Spring werken, is Spring MVC de gebruikelijke keuze voor de viewlaag. Er kan echter ook voor JSF en GWT gekozen worden.

roo$ web mvc setup

Hiermee worden allerlei template, property, CSS en image files en de tiles file views.xml toegevoegd en worden de descriptor files geconfigureerd (web.xml en webmvc-config.xml). Ook hier kan een huisstijl geïntroduceerd worden door deze files navenant aan te passen. In tegenstelling tot Forge wordt bij Roo ook meteen i18n support toegevoegd aan het project. Van de application.properties (voor algemene labels, berichten, etc.) en message.properties (voor domeinspecifieke labels, berichten, etc.) files kunnen taalspecifieke versies gemaakt worden.

Als laatste stap kunnen nu de webpagina's gegenereerd worden.

roo$ web mvc all --package ~.web

Behalve jsp document (.jspx) pagina's creëert dit commando ook een Spring MVC Controller klasse, genaamd EmployeeController (ook weer met bijbehorende Aspect4J file). Naast controller logica bevat deze klasse ook de koppeling naar de domein klasse Employee. Binnen de controller files wordt middels de @RequestMapping annotatie ervoor gezorgd dat de pagina's via Restful URL's te benaderen zijn.

Met behulp van de standaard aanwezige webserver in de IDE kan de applicatie nu gedeployed worden via Run As > Run On Server > VMWare vFabric tc Server. Als alternatief kan ook van de Jetty plugin gebruikt gemaakt worden.

Welkom-scherm Roo
Figuur 8: welkom scherm

Creeer Employee met Roo
Figuur 9: Create new Employee scherm

Lijst met Employees
Figuur 10: List Employees scherm

Een groot verschil tussen Spring Roo en Forge is dat eerstgenoemde vooral Stateless code genereert en de tweede via Stateful @Conversations werkt. Dit is een fundamenteel verschillende benadering. Het gaat te ver om er in dit Whitebook dieper op in te gaan, maar het zal zeker van invloed zijn bij de keuze voor een van beide frameworks.

Daarnaast werkt Roo veelvuldig met AspectJ. Dit levert hele schone code op, maar vereist wel een gedegen kennis van AspectJ. Het is hierbij de vraag of andere IDE's wel zo goed overweg kunnen met AspectJ als de STS.

Overige mogelijkheden

Ook Roo biedt uiteraard veel meer dan alleen CRUD-generatie commando's. Roo gaat daarin ook verder dan Forge. Een paar interessante voorbeelden zijn:

Spring security inregelen:

roo$ security setup

Dit verzorgt de setup van Spring security. Er worden 2 users gecreëerd, user en admin, alsmede een loginscherm voor bijbehorende authenticatie. Ook wordt basale authorisatie ingeregeld via URL-patronen.

REST/JSON support:

roo$ json all

roo$ web mvc json all

Hiermee worden de controller- en domein-klassen bijgewerkt, waarmee de applicatie via een REST/JSON API ontsloten wordt.

Verder biedt Roo support voor o.a. OSGi, JMS, Spring Web Flow, Cloud Foundry en Selenium tests. Support voor webservices ontbreekt vreemd genoeg nog.

Conclusie

Werken met een RAD-tool heeft als grote voordeel dat er vrij snel een werkende applicatie staat. Vooral tijdens de startup van een project of voor het maken van een demo kan dit een grote winst zijn. Het ontlast de ontwikkelaar met name van het goed inregelen van de diverse configuratiebestanden, zoals de pom.xml en persistence.xml, waardoor hij meteen aan de slag kan met de business-specifieke logica.

Zowel Roo als Forge doen hun werk uitstekend. Met minimale inspanning kan er snel een werkende enterprise-applicatie worden opgetuigd. Beide frameworks genereren Maven-projecten en zijn in staat om een modellaag te genereren die JPA- en Bean-validation ondersteunt. Voor wat betreft de Contoller/View laag genereert Forge JSF in combinatie met CDI. Roo ondersteunt ook JSF, maar logischer is het om hier voor Spring MVC te kiezen.

Roo is wat volwassener dan Forge. Zo genereert Roo out of the box een applicatie met i18n ondersteuning en kunnen er integratie- en Selenium-tests worden gegenereerd. Ook biedt Roo al NoSQL (vooralsnog alleen MongoDB) en Cloud-integratie (Cloud Foundry).

Interessant is ook om te kijken in hoeverre je uiteindelijk nog aanpassingen kan genereren als je binnen de gegenereerde klassen/schermen uiteindelijk toch een hoop maatwerk code hebt toegevoegd. Domein-objecten zijn hierbij bij beide frameworks nog prima aanpasbaar. Het toevoegen van velden of nieuwe contraints wordt in de bestaande klasse gedaan. Schermen- en controller- logica is een ander verhaal. Bij Forge heb je enkel de mogelijkheid om deze te laten overschrijven als een entiteit wordt aangepast. Roo gaat ook hierin een stuk verder. Indien je een veld toevoegt/aanpast binnen een entiteit worden ook de bestaande schermen en controller-files netjes bijgewerkt en niet overschreven.

Ook op het gebied van documentatie is Roo verder. De reference manual van Roo is uitgebreid en compleet, terwijl die van Forge compact is en weinig diepgang kent. Voor Roo is er bovendien al een Manning boek (Roo in Action) voorhanden.

Voor de rest is de keuze tussen beide vaak een no-brainer. Indien je gebonden bent aan JEE, is Forge de enige keuze, terwijl je bij Spring Enterprise applicaties juist voor Roo kiest. Bij hybride applicaties zouden beide frameworks kunnen voldoen, en is het vaak een kwestie van smaak. Hoewel Roo momenteel meer mogelijkheden kent, krijg je er wel standaard AspectJ bij. Dit levert hele schone code op, maar niet iedereen zal gecharmeerd zijn van alle extra AspectJ files.

Referenties

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.