Plus CD! n.
Transcrição
Plus CD! n.
Plus CD! Stellenmarkt 50 1.09 Liferay Enterprise Edition gives you all the benefits of open source with the stability, security, and reliability of an enterprise subscription. And with version 5.1, get the latest in SOA, Social Networking, and Collaboration technology, all at a fraction of the cost of Oracle ® or IBM ®. Liferay 5.1 Enterprise Edition Maintenance Subscription 2.950 EUR / server / year Platinum Support (24x7) 19.950 EUR / server / year Compare Oracle WebCenter Suite: 125.000 EUR / processor, support 27.500 EUR / yr, as of 6 / 2008 ® For more information, email us at [email protected]. REST – Das bessere Modell für Web Services? • Direct Web Remoting • SOA-Bausteine • JBoss Seam • Java-Memory-Modell Now get the best of both worlds. Deutschland € 7,50 Java Magazin Java Magazin 1.2009 You spoke. We listened. Introducing Liferay Enterprise Edition. Java • Architekturen • SOA • Agile 10 Österreich € 8,60 Schweiz sFr 15,80 www.javamagazin.de Exk l Abo usiv fü r nne nten OSG POS CD-Inhalt REST JAX TV: Session von der W-JAX 2008: Angelika Langer: Java-Programmierung im Multicore-Zeitalter • X Rendering Extension • JXRender Java-Frameworks • JBoss Seam 2.1.0 • Closures • Grails 1.0.4 • Hibernate 3.3.1 • Mylyn • Eclipse Equinox • Bnd Tool • Ext JS • Enterprise-Clustering • JBoss Cache 2.2.1 Alle CD-Infos 3 SOA Center SOA-Bausteine Jetzt wird’s konkret 88 Java Core Java-Memory-Modell Eine Roadmap zum Einsatz von volatile 21 Web JBoss Seam Klebstoff für Java EE 40 Best Practices DSLs mit Groovy Heiliger Gral für schnellere Software? 36 D 45 86 7 EUROPEAN HEADQUARTERS - LANGEN, GERMANY LIFERAY GMBH — ROBERT - BOSCH - STRASSE 11, 63225 LANGEN, GERMANY TEL: +49 - (0) 6103 - 3018570 Ý FAX: +49 - (0) 6103 - 3018571 WEB i TER 74 Das bessere Modell für Web Services? JAX-RS: Ein REST-orientiertes API 82 OSGi Runtimes • Apache Felix Web-Tools • DWR 2.0.5 Weihnachts-Special 56 DWR – Ajax-Anwendungen leichter implementieren Die Tage des klassischen Webs sind gezählt. Web 2.0 und Ajax haben dynamische Inhalte und hohe Interaktivität zur Selbstverständlichkeit werden lassen, bedeuten aber harte Programmierarbeit. Dank Direct Web Remoting lassen sich bestehende Webanwendungen jedoch mit erstaunlich geringem Aufwand „ajaxifizieren“. Web JBoss Seam Klebstoff für Java EE Mit JBoss Seam liegt ein Framework vor, das das Gebot der Leichtgewichtigkeit mit dem klassischen Java EE Stack kombinieren will. Es verspricht, die einzelnen Java-EEKomponenten mit einem speziellen „Klebstoff“ zu verbinden und so für den Entwickler die Grenzen zwischen den einzelnen Technologien zu verwischen. von Jan Groth und Frank Ratzlow ugegeben, seit einigen Jahren stellt das Erscheinen eines neuen Web Application Frameworks nicht unbedingt ein Ereignis dar, das die Java-Welt besonders aufhorchen Artikelserie: JBoss Seam Teil 1: JBoss Seam – Einordnung und Grundlagen Teil 2: Seam aus Entwicklersicht – eine Wanderung durch die Schichten Teil 3: Tools und Werkzeuge zur Unterstützung 40 javamagazin 1|2009 lässt. Anders sieht es aus, wenn eine derartige Meldung aus dem inneren Kreis der Java-Welt kommt – und zwar von Gavin King, dem Kopf hinter Hibernate. Dieser initiierte Seam bereits im Jahr 2005 und hat es seitdem geschafft, erstens JBoss als prominenten Unterstützer zu gewinnen und zweitens eine beachtliche Community um sich zu versammeln. Grund genug, einen Blick vor und hinter die Kulissen von Seam zu werfen. Klebstoff für Java EE Die Grundidee bei Seam besteht darin, bestehende JEE-Technologien nahtlos (seam-less) zu integrieren. Seam gehört damit also nicht in die Reihe derjenigen Frameworks, die dem traditionellen Java EE Stack den Rücken kehren, sondern liefert im Gegenteil eine Möglichkeit, einzelne Komponenten von Java EE auf einer höheren Abstraktionsebene miteinander in den Dialog treten zu lassen. Das Framework legt sich dabei als Fundament unter die Kerntechnologien EJB3, JSF, JPA/Hibernate und jBPM. Die konkrete Entwicklung erfolgt dabei klar gegen die jeweilige Technologie, Seam hält sich vornehm im Hintergrund und stellt lediglich die zur Kommunikation www.JAXenter.de JBoss Seam Web benötigte Querschnittsfunktionalität bereit. Aus der Ruby on Rails-Welt haben die Seam-Entwickler die Idee des Rapid Prototyping Tools übernommen. Ausgehend von einem Domänenmodell kann auch mit seam-gen eine komplette CRUD-Applikation generiert sowie ein Beispielprojekt erzeugt werden, per Mausklick bereits mit IDE-spezifischer Projektstruktur und Build-Skripten ausgestattet. Auch das Prinzip „Convention over Configuration“ wurde Rails entliehen. Damit soll es dem Entwickler schneller als bisher ermöglicht werden, einen funktionsfähigen Rahmen zu schaffen, der dann später Stück für Stück mit spezifischer Funktionalität ausgefüllt werden kann. Auf XML-Konfigurationsdateien wird weitgehend verzichtet, die meisten Einstellungen lassen sich alternativ per Annotation festlegen, bzw. sind verschiedenen Konventionen vorbelegt. Nachdem die Basisarbeit geleistet ist und die Umsetzung der Fachlichkeit ansteht, stößt man bei vielen WebFrameworks häufig sogleich an deren Limitationen. So kann es z.B. sein, dass man einen Datei-Upload benötigt, das Framwork einen solchen aber nicht anbietet und er erst mühsam programmiert werden muss. Auch kann es bei der Synchronisation von Zustandsinformationen zwischen verschiedenen Elementen zu Schwierigkeiten kommen. Seam bietet für solche Situationen einen Werkzeugkasten an, aus dem man sich bei Einzelfragen bedienen kann, der aber auch Architekturmuster beinhaltet. Wichtig ist herauszustreichen, dass es ausschließlich im Ermessen des Entwicklers liegt, was er nutzten möchte. Wie im weiteren Verlauf zu sehen ist, legt Seam zwar eher den Gebrauch von Stateful Session Beans nahe, erlaubt es aber trotzdem auch, in bekannter Manier mit Stateless Session Beans zu arbeiten, z.B. um Legacy-Code zu integrieren. Die Konzepte von Seam Eine Webanwendung besteht üblicherweise aus den drei Schichten Präsentation, Geschäftslogik und Persistenz. Verfolgt man den Weg eines einzelnen Request und achtet dabei auf die je- www.JAXenter.de Abb. 1: Die durch Seam verbundenen Technologien weiligen Zustände der durchlaufenen Schichten, so stellt man fest, dass es hier in der Regel zu einem Bruch kommt. Die typischerweise zustandsbehaftete Präsentationslogik trifft auf zustandslose Services in der Businesslogik, die wiederum mit zustandsbehafteteten Persistenzmanagern kommunizieren. Der Grund dafür liegt in der unterschiedlichen Lebensdauer der verschiedenen Kontexte, eine Synchronisation ist nur durch den Entwickler gewährleistet. Solange lediglich Geschäftsobjekte ausgetauscht werden, ist dies noch vergleichsweise einfach umzusetzen. Deutlich schwieriger wird es aber, wenn technische Ressourcen – z.B. eine Hibernate Session für Lazy Loading – über mehrere Schichten vorgehalten werden sollen. Daraus resultieren dann Workarounds der Art des „Open Session in View“-Patterns: Um Attribute einzelner Entitäten über deren komplette Verwendung hinweg ohne eine LazyInitializationException nachladen zu können, wird die Hibernate-Session von der Präsentationsschicht vorgehalten. Dies wäre komplett unnötig, wenn sowohl Präsentations- als auch Geschäftslogik eine Möglichkeit hätten, Ressourcen an einen gemeinsamen Kontext zu binden – das Backend würde die Hibernate-Session gerade so lange offen halten können, wie das Frontend diese benötigt. Komponenten und Kontexte Genau die eben beschriebene Situation – verbunden mit dem häufigen Fehlverständnis, das Problem auf Seiten von Hibernate zu suchen – war es, die Gavin King dazu veranlasst haben soll, das Seam-Projekt zu initiieren. Ein neues, zustandsbehaftetes Architekturkonzept verbindet die Komponenten einer Seam und JBoss Seam ist ein von JBoss gehostetes Projekt und steht unter der LGPL-Lizenz. Parallel existiert der JSR 299, der sich zur Aufgabe gemacht hat, die Konzepte von Seam als „Web Beans“ in einen offiziellen Standard zu überführen. Seam ist grundsätzlich auf allen JEE-Application-Servern lauffähig und hat keine spezifische Abhängigkeit zum JBoss AS, wenngleich Seam sicherlich unter JBoss am meisten getestet wurde. Neue Releases werden zurzeit gegen die folgenden Produkte getestet: JBoss AS 4.2, IBM WebSphere 6.1, WebLogic 10, GlassFish Version 2, Oracle OC4J 11g sowie Tomcat 5 bzw. 6. javamagazin 1|2009 41 Web JBoss Seam Abb. 2: Kontexte im Zusammenspiel Applikation miteinander und dient als einheitliches Vehikel für die Kommunikation in horizontale und vertikale Richtung. Die zentrale Idee ist in drei einfachen Schritten skizziert: Alle relevanten Objekte werden Seam bekannt gemacht, in diesem Zug vom Container mit einheitlicher Funktionalität dekoriert und somit zu Seam Components. Die aus der Java-Servlet-Spezifikation bekannten vier Scopes werden um zwei neue, zustandsbehaftete Typen erweitert, mit einem einheitlichen API versehen und zu Seam Contexts (Kasten: Seam-Context-Modell). Contexts und Components werden untrennbar miteinander verbunden und transparent vom Framework verwaltet. Noch etwas knapper: Ein Objekt wird zu einer Komponente, lebt in einem Kontext, hat dort in der Regel einen Zustand und kann über ein einziges API angesprochen werden. Mit dieser Idee im Kopf ist es nur noch ein kurzer Schritt, das bekannte „Inversion of Control“Design-Pattern einmal aus einer anderen Richtung zu betrachten, und zwar im wahrsten Sinne des Wortes. Zur Erinnerung: Wenn es um die Entkopplung von Verantwortlichkeiten geht, ist Inversion of Control das zentrale Pattern. Abhängigkeiten werden nicht programmiert, sondern konfiguriert und erst zur Laufzeit aufgelöst. Der bekannteste Vertreter in diesem Bereich ist ohne Zweifel das Spring Framework: Ein Spring Bean deklariert die benötigten Ressourcen nur allgemein und überlässt es dem Spring-Container, diese zum Entstehungszeitpunkt geeignet zu instanziieren und korrekt zu injizieren. Dieses Vorgehensmodell ist außerordentlich mächtig und effizient. Es erhöht die Wiederverwendbarkeit eines Beans, reduziert Verantwortlichkeiten und verschlankt Code. Seam greift das Prinzip auf und erweitert es. Bijection Es ist sowohl möglich, Abhängigkeiten aus einem bestimmten Kontext in eine Komponente hinein zu injizieren (englisch: Injection), als auch den Weg in Gegenrichtung zu beschreiten, also Abhängigkeiten aus einer Komponente heraus in einen Scope zurückzuschreiben (neu- Seam-Context-Modell: Die Erweiterung der Servlet Scopes Während der Entwicklung einer Webapplikation ist es häufig notwendig, eine in sich geschlossene Folge von Seiten umzusetzen, die jeweils einen Anwendungsfall aus dem Anforderungskatalog abbildet. Kandidaten für solche Use Cases sind Nutzerregistrierung, Bestellabwicklung oder auch die Pflege des eigenen Profils. Beispielsweise werden in einer typischen Portalregistrierung zunächst über mehrere Seiten die benötigten Daten abgefragt, anschließend komplexe Validierungen durchgeführt, danach eine Aktivierungsmail versendet und erst nach erfolgreichem Abschluss dieser Schritte ein Benutzeraccount im System angelegt. In der Umsetzungsphase stellt man schnell fest, dass die Standard-Scopes des Servlet-APIs hier unpassend sind. Der Request Scope ist zu klein – bei jedem Server Roundtrip gehen die Daten zunächst verloren und müssen über Umwege wiederhergestellt werden. Der Session Scope wiederum ist zu groß, hier stehen die Daten über die gesamte Nutzersession hinweg zur Verfügung, aus Sicht eines einzelnen Prozesses eindeutig zu lang, und aus Entwicklersicht speicherintensiv und fehlerträchtig. Egal wie man sich nun behilft, in jedem Fall ist die Lösung ein Kompromiss. Seam adressiert dieses Problem durch die Einführung eines neuen Kontexts, dem Conversation Context. Dessen Gültig- 42 javamagazin 1|2009 keitszeitraum bewegt sich genau zwischen Request und Session und wird direkt vom Entwickler gesteuert. Hierfür werden Start- und Endpunkt(e) im entsprechenden Methodenaufruf festgelegt, im obigen Beispiel z.B. dem initialen Aufruf der Registrierungsseite als Startpunkt, und dem erfolgreichen Mailversand sowie allen Fehlerausgängen als Endpunkte. Innerhalb dieser Grenzen ist der Conversation Context aktiv, alle dort registrierten Komponenten behalten ihren Zustand und können vom Entwickler uneingeschränkt verwendet werden. Einen Schritt weiter gedacht ist der Versand einer Aktivierungsmail natürlich noch gar nicht das Ende des Registrierungsprozesses – ausstehend sind noch die Antwort des Benutzers und die endgültige Freischaltung des Kontos, beides also asynchrone Schritte. Auch diverse Schnörkel am Rande, beispielsweise die Option zum Neuversand der Mail, fallen in diese Kategorie. Hiermit wird die Welt der Geschäftsprozesse betreten. Es sei daher nur kurz erwähnt, dass Seam zusätzlich noch das jBPM integriert und es damit möglich ist, derartige Prozesse zu modellieren, zu steuern und entsprechend in der Datenbank zu persistieren. Zu diesem Zweck existiert mit dem Business Process Context ein eigener Kontext, der den Gültigkeitsbereich des Application Scopes noch erweitert. www.JAXenter.de JBoss Seam Web englisch: Outjection). Alles zusammen wird mit dem Kunstwort „Bijection“ bezeichnet und beschreibt die Fähigkeit des Seam-Containers, Abhängigkeiten von Komponenten untereinander zu verwalten und zur Zugriffszeit dynamisch aufzulösen – wohlgemerkt zum Zugriffszeitpunkt, nicht zum Entstehungszeitpunkt. In der Praxis werden dazu Beginn und Ende eines Methodenaufrufs einer Seam-Komponente vom Container abgefangen und entsprechende Bijectionen ausgeführt. Ein Beispiel (Abb. 2): RegistrationManager ist eine für einen Registrierungs-Flow verantwortliche Seam-Komponente, Reg_1 und Reg_2 sind entsprechende FaceletsTemplates dazu. Der graue Kreis stellt das gemeinsam genutzte Objekt User dar. Die Beschreibung bewegt sich entlang der Zeitachse von links nach rechts: 1.Das Feld User am Manager ist zur Bijection definiert. 2.Eine Initialisierungsmethode am Manager erzeugt einen User und startet eine neue Conversation. 3. Beim Verlassen der Methode wird der User von Seam in den Kontext der Conversation geschrieben (Outjection). 4.Reg_1 wird gerendert, dabei kann per JSF Expression Language verwendet werden. Seam löst die Referenz automatisch durch eine aufsteigende Suche durch die Kontexte auf und wird in der Conversation fündig. 5. Beim Submit durch Reg_1 werden Änderungen am User übernommen und dieser in die Conversation zurückgeschrieben. 6. Reg_2 verwendet das User-Objekt analog zu Reg_1. 7.B ei der Übergabe des Kontrollflusses zurück an den Manager (z.B. durch den Aufruf einer register()-Methode) werden vor dem Betreten der Methode die Abhängigkeiten der Komponente aufgelöst – der aktuelle User also aus der Conversation heraus in den Manager geschrieben (Injection). 8.Die Conversation wird vom Manager beendet, und damit werden alle Objekte im Kontext freigeben. Ein kurzer Blick auf die relevanten Codezeilen verdeutlicht die Umsetzung, Zunächst der RegistrationManger: 1 ... 2 @Name(”RegistrationManager“) 3 @Scope(ScopeType.CONVERSATION) 4 public class RegistrationManager { 5 ... 6 @In @Out private User user; 7 ... 8 @Begin(pageflow = ”registrationFlow“) 9 public init() {...user = new User()...} 10 ... 11 @End 12 public register() {} 13 ... 14 } Anzeige 4 Web JBoss Seam In den Zeilen 2 und 3 erfolgt die Registrierung der Klasse als Seam Component im Conversation Context. Die Bijection für den User wird über @In- und @Out-Annotation in Zeile 6 festgelegt. Schließlich noch die Methoden init(), die den zugrunde liegenden Pageflow (und damit die Conversation) startet und den User initialisiert und register(), die die Conversation beendet. Beispielhaft aus einer JSF-Seite die Erfassung des Benutzernamens: keine einzige Seite entwickelt. Dass das auch anders geht, ist spätestens seit Ruby on Rails bekannt. Seam hat die Idee aufgegriffen und der Distribution mit seam-gen ein Tool beigefügt, das aus der Kommandozeile heraus mit wenigen Befehlen zu bedienen ist. Nach dem ersten Start wird eine Liste von ca. 20 Fragen ab- Ballast mitzuschleifen. Typische Problemstellungen der Webentwicklung können elegant und vor allem ohne Hilfskonstrukte und Umwege gelöst werden. Aber bei so viel Mächtigkeit ist natürlich auch Vorsicht geboten: Ein hohes Maß an Verständnis sowohl der verwendeten Technologien als auch der Seam-Konzepte wird unbedingt vorausgesetzt. Denn gerade der „Convention over Configuration“-Ansatz hat zur Folge, dass viele Dinge automatisch im Hintergrund ablaufen, und ein unerfahrener Entwickler möglicherweise nicht mehr versteht, was sich alles abspielt. Und spätestens beim Debuggen bzw. der Wartung ist es notwendig, auch die implizit gesetzten Parameter zu verstehen. Es darf einfach nicht vergessen werden, dass hier mit EJB3, JSF, JPA und jBPM einige Technologien verwendet werden, die jede für sich Stoff für diverse Fachbücher und Artikel bieten. Die Liste ist lang und das Terrain unbekannt. 1 <h:form> 2 ... 3 <h:inputText id=“firstName“ required=“true“ value=“#{user.firstName}“ /> 4 ... 5 <h:commandButton action=“next“ value=“#{messages.newCustomerPrompt}“ /> 6 </h:form> Zu sehen ist hier in erster Linie der User, der nach dessen Referenzierung per EL von Seam aus dem Conversation Context in die JSF hinein injiziert und nach dem Submit auch wieder dorthin zurückgeschrieben wird. Wer an dieser Stelle mit mehr Code gerechnet hat, wird enttäuscht. Zwar fehlt die Definition des Pageflows, und auch die Instanziierung des Users würde in der Praxis wohl delegiert werden, aber grundsätzlich ist hier der komplette Mechanismus des Beispiels umgesetzt. Aus Autorensicht fällt es schwer, sich ein „Gar nicht schlecht, oder?“ zu verkneifen. Schneller Start mit seam-gen Wer kennt nicht das Problem, sich in einer neuen Technologie zu orientieren? Das neue Framework ist heruntergeladen, das erste Tutorial durchgespielt, erfolgreich deployt, und im Browserfenster ist auch schon „Hello World“ zu lesen. Der Schritt zwischen einer trivialen Zwei-Seiten-Webapplikation und einem praxistauglichen Setup ist allerdings gewaltig. Eine Projektstruktur muss festgelegt werden, Konfigurationen angelegt, Build-Prozesse und Testvorgehen definiert werden – die Liste ist lang und das Terrain unbekannt. Und wenn endlich alles steht, ist immer noch 44 javamagazin 1|2009 gearbeitet, dabei entscheidet der Benutzer über Dinge wie Projekt- und Packagenamen und zu unterstützende Datenbank. Das Ergebnis ist ein fertiges Eclipse-Projekt, inklusive Konfigurationsdateien für verschiedene Umgebungen, Build-Skripten und wahlweise auch ersten Tests. Dazu wird, sofern gewünscht, eine CRUDApplikation des existierenden Datenmodells generiert. Falls kein komplettes Projekt benötigt oder gewünscht wird, besteht die Möglichkeit, selektiv Elemente einem existierenden Projekt hinzuzufügen – z.B. CRUD-Masken für eine neue Entität. Unter der Haube besteht seam-gen aus einem ant-Script in Kombination mit Hibernate-Tools. Für fortgeschrittene Anwendungsfälle können die in Freemarker [1] erstellten Code-Templates für die eigenen Zwecke angepasst werden. Die Entwickler von seam-gen werden nicht müde, den Einsatz des Tools zu empfehlen. Gavin King schreibt dazu im JBoss-Forum: „There really are a LOT of advantages to starting with the seam-gen structure. I did a lot of work on things that will take you a while to reproduce if you try to do it all from scratch. (like, weeks of work!) However, there‘s nothing magical about it, and other structures can work just as well.“ [2]. Zusammenfassung Das Seam-Framework präsentiert einen Ansatz, die zentralen JEE-Technologien miteinander zu verbinden, ohne die schwergewichtigen Themen aus der Enterprise-Welt als offensichtlichen Jan Groth ist bei der adesso AG in Berlin beschäftigt. Dort ist er als Technischer Projektleiter für Planung und Umsetzung von Kundenprojekten im JEE-Umfeld verantwortlich. Frank Ratzlow ist ebenfalls bei der adesso AG beschäftigt, als Systemarchitekt befasst er sich mit Architekturen im JEE- und Spring-Bereich. Fragen und Feedback zum Artikel sehr gerne an [email protected] Links & Literatur [2] www.jboss.com/index.html?module =bb&op=viewtopic&p=4030018 [1] freemarker.org [3] docs.jboss.com/seam/2.1.0.GA/ reference/en-US/html/ [4] www.seamframework.org/Community/GettingStartedDevelopingTheSeamFramework [5] java.sun.com/javaee/technologies/ www.JAXenter.de