Fr 2 January 21-25, 2008, Munich, Germany ICM - International Congress Centre Munich State-of-the-Art Enterprise Java Lars Röwekamp Jens Schumann Contents State-of-the-Art Enterprise Java - Part 1 .................................................1 Lars Röwekamp & Jens Schumann State-of-the-Art Enterprise Java - Part 2 .................................................39 Lars Röwekamp & Jens Schumann „State-of-the-Art Enterprise Java“ - Teil 1 OOP 2008 Lars Röwekamp - CIO New Technologies - Jens Schumann - CTO Development - Agenda Wie alles begann Am Anfang war eine Idee Von der Idee zur Lösung Enterprise Java - Basic Version Enterprise Java Grundprinzipien Technologie Entscheidung Technologie Lösung Ist das alles? Technologie Probleme Enterprise Java - Enhanced Version Real (Enterprise) Life Probleme Real (Enterprise) Life Lösungen 1 Agenda Wie alles begann Am Anfang war eine Idee Von der Idee zur Lösung Enterprise Java - Basic Version Enterprise Java Grundprinzipien Technologie Entscheidung Technologie Lösung Ist das alles? Technologie Probleme Enterprise Java - Enhanced Version Real (Enterprise) Life Probleme Real (Enterprise) Life Lösungen State-of-the-Art Enterprise Java / Wie alles begann Am Anfang war ... eine Idee 2 State-of-the-Art Enterprise Java / Wie alles begann Wir erobern ... die Welt State-of-the-Art Enterprise Java / Wie alles begann „Langweilige Online- Reiseagenturen waren gestern heute ist openTravel Agency“ 3 State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency: Anforderungen State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency - Anforderungen Time-to-Market 4 State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency - Anforderungen flexibel, erweiterbar State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency - Anforderungen skalierbar 5 State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency - Anforderungen performant Zur Anzeige wird der QuickTime™ Dekompressor „TIFF (Unkomprimiert)“ benötigt. State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency - Anforderungen Ach ja, darf nix kosten 6 State-of-the-Art Enterprise Java / Wie alles begann openTravel Agency: Von der Idee zur Lösung State-of-the-Art Enterprise Java Von der Idee zur Lösung: Man nehme .... eine Hand voll ... 7 State-of-the-Art Enterprise Java Von der Idee zur Lösung: und nehme dazu .... eine Hand voll ... State-of-the-Art Enterprise Java Von der Idee zur Lösung: und schon bekommt man ... eine Hand voll ... 8 State-of-the-Art Enterprise Java / Von der Idee zur Lösung Lösungsvarianten: „Web 2.0“ Ruby on Rails Groovy on Grails Rein JSP basierte Lösung JSP plus Java SE „Rund-um-sorglos-Paket“ z.B. jBoss SEAM Flexible Mehrschicht-Architektur Standard basiert: Java EE 5 inkl. JSF Quasi Standard basiert: JSF, Spring und Hibernate State-of-the-Art Enterprise Java / Von der Idee zur Lösung Lösungsvarianten: „Web 2.0“ Ruby on Rails Groovy on Grails Rein JSP basierte Lösung JSP plus Java SE „Rund-um-sorglos-Paket“ z.B. jBoss SEAM Flexible Mehrschicht-Architektur Standard basiert: Java EE 5 inkl. JSF Quasi Standard basiert: JSF, Spring und Hibernate 9 State-of-the-Art Enterprise Java / Von der Idee zur Lösung Flexible Mehrschicht-Architektur Standard basiert: Java EE 5 inkl. JSF Java EE ist in der Vergangenheit in „Verruf“ geraten Java EE (<5) Spezifikation wurde am Reisbrett an der Realität vorbei erstellt Java EE 5 scheint aus den Fehlern der Vergangenheit gelernt zu haben Java EE 5 muss sich allerdings am Markt erst noch beweisen Quasi Standard basiert: JSF, Spring und Hibernate füllt geschickt die Lücke, welche Java EE (<5) hinterlassen hat stark verbreitet, d.h. es gibt eine große Community / Lobby etabliert, d.h. es gibt viele Referenzprojekte funktioniert (sehr gut) dokumentiert (sehr gut) Agenda Wie alles begann Am Anfang war eine Idee Von der Idee zur Lösung Enterprise Java - Basic Version Enterprise Java Grundprinzipien Technologie Entscheidung Technologie Lösung Ist das alles? Technologie Probleme Enterprise Java - Enhanced Version Real (Enterprise) Life Probleme Real (Enterprise) Life Lösungen 10 State-of-the-Art Enterprise Java / Basic Version Enterprise (Java) Grundprinzipien Saubere Mehrschicht-Architektur Schichtentrennung via Interfaces Model-View-Controller Pattern Gut durchdachtes Modell Trennung von Domain Modell und DB Modell Inversion of Control Aspekte Testbarkeit (siehe Teil 2) Deployment und Build Management (siehe auch Teil 2) State-of-the-Art Enterprise Java / Basic Version Enterprise (Java) Grundprinzipien - Visualisierung Trennung von Inhalt Layout Widerverwendung Komponenten Template Mechanismus / Snippets Ereignis orientiert scheint intuitiver als Request / Response hat sich in der Desktop Welt bewährt 11 State-of-the-Art Enterprise Java / Basic Version Enterprise (Java) Grundprinzipien - Domain Modell Domain Model repräsentiert die umzusetzende Fachlichkeit! Nicht mehr Nicht weniger Domain Model kann abweichen von DB Model Visualization Model State-of-the-Art Enterprise Java / Basic Version Enterprise (Java) Grundprinzipien - Persistenz Load Verhalten Load all vs. Lazy Loading OR Mapping manuell vs. generiert Concurrency Optimistic Locking vs. Pessimistic Locking Transaktionen Allgemein vs. individuell 12 State-of-the-Art Enterprise Java / Basic Version Technologie Entscheidung Primärer Stack JSF 1.1 (myFaces Implementierung) Spring 2.0 Hibernate 3.2 plus Apache Tomahawk JSF Komponenten Tiles 2 Template Library plus ANT Build Management State-of-the-Art Enterprise Java / Basic Version Technologie Entscheidungen / Herausforderungen Warum und wie ... verbinde ich JSF mit Spring? verbinde ich JSF mit Hibernate? verbinde ich Spring mit Hibernate? 13 State-of-the-Art Enterprise Java / Basic Version Technologie Detail Herausforderungen Entscheidungen, wie zum Beispiel ... Visualisierung Warum und wie binde ich Tiles 2 in JSF ein? Persistenz Wie erzeuge ich mein OR Mapping? Welches Load Verhalten soll ich wählen? Welches Lock Verhalten soll ich wählen? Wie behandele ich meine Transaktionen? State-of-the-Art Enterprise Java / Basic Version Technologie Herausforderung / Entscheidung Warum verbinde ich JSF mit Spring? IOC basierter Zugriff aus JSF Manged Beans heraus auf Spring Managed Beans Wie verbinde ich JSF mit Spring? 1. Spring Einbindung via ContextListener 2. Spring Einbindung via ContextServlet (alternativ) 3. JSF spezifische Einbindung via DelegatingVariableResolver 14 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich JSF mit Spring? 1. Allgemeine Spring Einbindung via ContextListener <!-- web.xml --> ... <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> ... <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/applicationContext*.xml </param-value> </context-param> ... State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich JSF mit Spring? 2. Allgemeine Spring Einbindung via ContextServlet <!-- web.xml --> ... <servlet> <servlet-name>context</servlet-name> <servletclass> org.springframework.web.context.ContextLoaderServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> ... <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/applicationContext*.xml </param-value> </context-param> ... 15 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich JSF mit Spring? 3. JSF spezifische Einbindung via DelegatingVariableResolver <!-- faces-config.xml --> <faces-config> <application> <variable-resolver> org.springframework.web.jsf.DelegatingVariableResolver </variable-resolver> </application> ... </faces-config> State-of-the-Art Enterprise Java / Basic Version Technologie Herausforderung / Entscheidung Warum verbinde ich JSF mit Hibernate? JSF ist UI zentriertes Framework Anbindung an Mittelschicht ist Aufgabe von JSF Anbindung an Persistenz ist „eigentlich“ nicht Aufgabe von JSF (siehe „advanced Version“) Wie verbinde ich JSF mit Hibernate? Gar nicht ... 16 State-of-the-Art Enterprise Java / Basic Version Technologie Herausforderung / Entscheidung Warum verbinde ich Spring mit Hibernate? Einfaches Testen der DOAs „normalisierte“ DataAccessException Hierachie „normalisiertes“ Ressourcen Management Integriertes Transaktionsmanagement Wie verbinde ich Spring mit Hibernate? 1. Hibernate SessionFactory Setup 2. DAO Implementierung 3. Transaction Management State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 1. Hibernate SessionFactory Setup 1/2 <beans> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <bean ... </bean> </beans> <!-- Session Factory --> 17 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 1. Hibernate SessionFactory Setup 2/2 <beans> <bean> .... </bean> <!-- DataSource --> <bean id="mySessionFactory" class="org.sf.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <property name="mappingResources"> <list> <value>product.hbm.xml</value> </list> </property> <property name="hibernateProperties"> <value> hibernate.dialect=org.hibernate.dialect.HSQLDialect </value> </property> </bean> </beans> (org.sf.orm = org.springframework.orm) State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung 2.a unter Verwendung von pure Hibernate 2.b unter Verwendung des HibernateTemplates 2.c unter Verwendung der HibernateDaoSupport Klasse 18 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „für alle Ansätze“ <beans> <bean id="myProductDao" class="product.ProductDaoImpl"> <property name="sessionFactory" ref="mySessionFactory"/> </bean> ... </beans> State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „pure Hibernate“ public class ProductDaoImpl implements ProductDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public Collection loadProductsByCategory(String category) { return this.sessionFactory .getCurrentSession() .createQuery("...") .setParameter(0, category) .list(); } } 19 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „HibernateTemplate“ public class ProductDaoImpl implements ProductDao { private HibernateTemplate hibernateTemplate; private final static queryString = “...“; public void setSessionFactory(SessionFactory sessionFactory) { this.hibernateTemplate = new HibernateTemplate(sessionFactory); } public Collection loadProductsByCategory(String category) throws DataAccessException { return this.hibernateTemplate.find(queyrString, category); } } State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „HibernateDaoSupport - mit Template Nutzung“ public class ProductDaoImpl extends HibernateDaoSupport implements ProductDao { private final static queryString = "..."; public Collection loadProductsByCategory(String category) throws DataAccessException { return this.hibernateTemplate.find(queyrString, category); } } 20 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „HibernateDaoSupport - ohne Template Nutzung“ public class HibernateProductDao extends HibernateDaoSupport implements ProductDao { public Collection loadProductsByCategory(String category) throws DataAccessException, MyException { Session session = getSession(false); try { Query query = session.createQuery("...";); query.setString(0, category); List result = query.list(); if (result == null) { throw new MyException("No search results."); } return result; } catch (HibernateException ex) { throw convertHibernateAccessException(ex); } } } State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 2. DAO Implementierung: „Hibernate Callback“ public class ProductDaoImpl implements ProductDao { ... /* Using Hibernate Callback as direct access method */ public Collection loadProductsByCategory(final String category) throws DataAccessException { return this.hibernateTemplate.execute(new HibernateCallback() { public Object doInHibernate(Session session) { Criteria criteria = session.createCriteria(Product.class); criteria.add(Expression.eq("category", category)); criteria.setMaxResults(6); return criteria.list(); } }; } } 21 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.a programmatische Transaktionsabgrenzung 3.b deklarative Transaktionsabgrenzung State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.a programmatische Transaktionsabgrenzung 1/3 <beans> <bean id="myTxManager" class="org.sf.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory"/> </bean> <bean id="myProductService" class="product.ProductServiceImpl"> <property name="transactionManager" ref="myTxManager"/> <property name="productDao" ref="myProductDao"/> </bean> </beans> (org.sf.orm = org.springframework.orm) 22 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.a programmatische Transaktionsabgrenzung 2/3 public class ProductServiceImpl implements ProductService { private TransactionTemplate transactionTemplate; private ProductDao productDao; public void setTransactionManager(PlatformTransactionManager txManager){ this.transactionTemplate = new TransactionTemplate(txManager); } public void setProductDao(ProductDao productDao) { this.productDao = productDao; } public void increasePriceOfAllProductsInCategory(String category) { ... } } State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.a programmatische Transaktionsabgrenzung 3/3 public class ProductServiceImpl implements ProductService { ... public void increasePriceOfAllProductsInCategory(String category) { this.transactionTemplate.execute( new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult( TransactionStatus status) { List productsToChange = productDao.loadProductsByCategory(category); // do the price increase for all products ... } } ); } } 23 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.b deklarative Transaktionsabgrenzung 1/3 <beans> <bean id="myTxManager" class="org.sf.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="mySessionFactory"/> </bean> <bean id="myProductService" ... </bean> </beans> (org.sf.orm = org.springframework.orm) State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.b deklarative Transaktionsabgrenzung 2/3 <beans> <bean id="myTxManager“ ...> ... </bean> <bean id="myProductService" class="org.sf.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="product.ProductService"/> <property name="target"> <bean class="product.DefaultProductService"> <property name="productDao" ref="myProductDao"/> </bean> </property> <property name="interceptorNames"> <list> <value>myTxInterceptor</value> <!-- TX interceptor --> </list> </property> </bean> </beans> 24 State-of-the-Art Enterprise Java / Basic Version Technologie Lösung Wie verbinde ich Spring mit Hibernate? 3. Transaction Management 3.b deklarative Transaktionsabgrenzung 3/3 public private class ProductServiceImpl implements ProductDao public void setProductDao(ProductDao this.productDao = productDao; } ProductService { productDao; productDao) { // notice the absence of transaction demarcation code in this method public void increasePriceOfAllProductsInCategory(String category) { List productsToChange = productDao.loadProductsByCategory(category); // do the price increase for all products ... } } State-of-the-Art Enterprise Java Travel Agency „Basic Version“ 25 State-of-the-Art Enterprise Java / Basic Version Ist das alles? Technologie Probleme Konfiguration Overkill Library Overkill Spring Probleme Kein Zugriff von Spring Managed Beans auf JSF Managed Beans Kein expliziter Zugriff auf Spring Managed Beans Hibernate Probleme Hohe Antwortzeiten bei Datenbank Interaktion Hibernate Session Probleme bei Verwendung von Objekten in der UI Explizites, deklaratives Transaktionsmanagement ist zu aufwendig Agenda Wie alles begann Am Anfang war eine Idee Von der Idee zur Lösung Enterprise Java - Basic Version Enterprise Java Grundprinzipien Technologie Entscheidung Technologie Lösung Ist das alles? Technologie Probleme Enterprise Java - Enhanced Version Real (Enterprise) Life Probleme - explained Real (Enterprise) Life Probleme - solved 26 State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill“ - explained web.xml, tiles, persistence, faces-config, applicationContext Zwei IOC Konfigurationen für Managed Beans Spring applicationContext.xml JSF faces-config.xml OR Mapping Deklarationen hbm.xml pro Klasse State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill - zwei IOC Konfigurationen“ - explained 27 State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill - zwei IOC Konfigurationen“ - explained State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill - zwei IOC Konfigurationen“ - solved Seit Spring 2.0 Custom Scopes „request“ und „session“ - nur noch applicationContext.xml <beans> <bean id="myService" class="de.openKnowledge.travel.service.MyService" /> <!-- could be referenced within a JSF via #{myBean} --> <bean id="myBean" class="de.openKnowledge.travel.bean.MyBean“ scope="request" /> <property name="service"> <ref bean=“myService" /> </property> </bean> </beans> 28 State-of-the-Art Enterprise Java / Enhanced Version Konfiguration Overkill - zwei IOC Konfigurationen“ - solved AOP Trick für Scope Mismatches <beans> <bean id="myService" class="de.openKnowledge.travel.service.MyService"> <property name="user"> <ref bean=“userBean" /> </property> </bean> <bean id=“userBean" class="de.openKnowledge.travel.bean.User“ scope="session" /> <aop:scoped-proxy /> </bean> </beans> State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill - OR Mapping Deklarationen“ - explained hbm.xml Datei pro zu persistierender Klasse Klasse, welche persitiert werden soll Tabelle(n) Primary Key Generator Java Klasse / Tabelle(n) Feld Mappings Beziehungen zu anderen Klassen, inkl. Cascading Strategie, z.B. delete-all-orphan Loading Strategie, z.B. lazy=„true“ 29 State-of-the-Art Enterprise Java / Enhanced Version „Konfiguration Overkill - OR Mapping Deklarationen“ - solved Generieren der Mappings via Hibernate xDoclet Umstieg auf Hibernate mit Annotations Umstieg auf JPA mit Annotations JPA kann als Wrapper für Hibernate genutzt JPA Vorteil Java Standard API Wrapper für beliebige OR Mapper State-of-the-Art Enterprise Java / Enhanced Version „Library Overkill“ - explained unzählige Libraries für Hibernate, Spring und JSF Probleme durch Versionskonflikte Probleme durch Library Abhängigkeiten Probleme durch lokale Server Konfiguration Probleme durch lokale Server Libs 30 State-of-the-Art Enterprise Java / Enhanced Version „Library Overkill“ - solved Umstellen des Build-/Deployment-Management von ANT auf MAVEN 2 inkl. Dependencies Nutzen von Server Plug-Ins Tomcat Plug-In Jetty Plug-In State-of-the-Art Enterprise Java / Enhanced Version „Spring Problem - expliziter Zugriff“ - explained Zugriff auf Spring Manged Beans via DelegateVariableResolver DelegateVariableResolver 1. Schaut, ob gesuchte Bean via JSF deklariert ist 2. Lookup erfolgt in der Spring Konfiguration 31 State-of-the-Art Enterprise Java / Enhanced Version „Spring Problem - expliziter Zugriff“ - solved Expliziter Zugriff durch Verwendung der FacesContextUtil Klasse /* beliebiger Java Code */ ... ApplicationContext ctx = FacesContextUtils.getWebApplicationContext( FacesContext.getCurrentInstance()); ... BeanFactory factory = (BeanFactory) context; MyClass bean = (MyClass)factory.getBean(“MyClass“, MyClass.class); ... State-of-the-Art Enterprise Java / Enhanced Version „Spring Problem - bidirektionaler Zugriff“ - explained JSF Managed können auf Spring Managed Bean zugreifen Spring Managed können NICHT auf JSF Managed Beans zugreifen Originäre Zugriffsmöglichkeiten (siehe oben): Deklarativer Zugriff via DelegateVariableResolver Programmativer Zugriff via FacesContextUtil 32 State-of-the-Art Enterprise Java / Enhanced Version „Spring Problem - bidirektionaler Zugriff“ - solved Verwendung spezialisierter 3rd Party Library „JSF-Spring“ von mindmatters bidirektionale Integration direkte Spring MVC Integration GET Form submit via Faclets RESTful Web Application via Facelets State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - Load Times“ - explained Lange Load Times bei DAO Zugriffen Laden unnötig vieler, angehängter Daten durch fehlende Angabe der LAZY Fetch Strategie fehlende Angabe der Fetch Tiefe 33 State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - Load Times“ - solved (?) Verwenden einer Lazy Fetch Strategie ABER: führt evtl. zu neuen Problemen in der UI! UI Problem bei Lazy Fetching umgehen (siehe unten) OpenSessionInViewFilter EntityManager merge State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - not in session“ - explained JSF LifeCycle und Hibernate Session nicht „in sync“ Hibernate Session bereits geschlossen, Objekt wird noch verwendet Sicherstellen: Innerhalb eines Requests genau eine Session Innerhalb mehrerer Requests mit aktueller Session refreshen/mergen Stichwort: Open Session per View/Request Pattern 34 State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - not in session“ - solved Wohldefinierten Start- und Endpunkt für Hibernate Session Spring Framework OpenSessionInViewFilter <-- web.xml --> ... <filter> <filter-name>sessionFilter</filter-name> <filter-class> org.sf.orm.hibernate3.support.OpenSessionInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>sessionFilter</filter-name> <url-pattern>*.jsf</url-pattern> </filter-mapping> ... State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - deklaratives TX Management“ - explained zur Erinnerung: AOP ProxyFactoryBean - Deklaration je Klasse <beans> <bean id="myTxManager" ... </bean> <bean id="myProductService" class="org.sf.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="product.ProductService"/> <property name="target"> <bean class="product.DefaultProductService"> <property name="productDao" ref="myProductDao"/> </bean> </property> <property name="interceptorNames"> <list> <value>myTxInterceptor</value> <!-- the transaction interceptor --> </list> </property> </bean> </beans> (org.sf.orm = org.springframework.orm) 35 State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - deklaratives TX Management“ - solved Allgemeines, deklaratives Transaktionsmanagement via AOP - 1/2 <beans> <!-- SessionFactory, DataSource, etc. omitted --> <bean id="myTxManager“> ... </bean> <aop:config> <aop:pointcut id=“serviceMethods" expression="execution(* service.*Service.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref=“serviceMethods"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="myTxManager"> ... </tx:advice> <bean id="myProductService" class=“service.product.SimpleProductService"> ... </bean> </beans> State-of-the-Art Enterprise Java / Enhanced Version „Hibernate Problem - deklaratives TX Management“ - solved Allgemeines, deklaratives Transaktionsmanagement via AOP - 2/2 <beans> <!-- SessionFactory, DataSource, etc. omitted --> <bean id="myTxManager" ... </bean> <aop:config> ... </aop:config> <tx:advice id="txAdvice" transaction-manager="myTxManager"> <tx:attributes> <tx:method name="increasePrice*" propagation="REQUIRED"/> <tx:method name="someOtherBusinessMethod" propagation="REQUIRES_NEW"/> <tx:method name="*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <bean id="myProductService" ... </bean> </beans> 36 State-of-the-Art Enterprise Java Travel Agency „Advanced Version“ OOP 2008 - State-of-the-Art Enterprise Java Fazit JSF, Spring und Hibernate/JPA Integration Ist dokumentiert - schön! Funktioniert - noch schöner! Erste Lösung ist relativ einfach Erste Lösung ist nicht gleich beste Lösung Wie immer gilt: „wisse was du tust“ Es gibt Wissen am Markt Communities Consultants 37 OOP 2008 - State-of-the-Art Enterprise Java Java Persistence API myFaces Hibernate Fragen? JSF RI Spring 2.0 Java EE Web 2.0 IOC Tomahawk OOP 2008 - State-of-the-Art Enterprise Java Vielen Dank! Lars Röwekamp CIO New Technologies Jens Schumann CTO Development OpenKnowledge GmbH Bismarckstr. 13 26122 Oldenburg Tel.: +49 (441) 40 82 - 0 [email protected] 38 „State-of-the-Art Enterprise Java“ - Teil 2 OOP 2008 Lars Röwekamp - CIO New Technologies - Jens Schumann - CTO Development - State-of-the-Art Enterprise Java Was bisher geschah… 39 State-of-the-Art Enterprise Java / Was bisher geschah Am Anfang war ... eine Idee State-of-the-Art Enterprise Java / Was bisher geschah Wir erobern ... die Welt 40 State-of-the-Art Enterprise Java / Was bisher geschah „Langweilige Online- Reiseagenturen waren gestern heute ist openTravel Agency“ Agenda Enterprise Java - Know-How Check GOF und J2EE 1.4 Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise Java - Build Management und Deployment 41 Agenda Enterprise Java - Know-How Check GOF und J2EE 1.4 Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise Java - Build Management und Deployment State-of-the-Art Enterprise Java / Know-How Check GOF Pattern J2EE 1.4 Pattern 42 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Singleton J2EE 1.4 Pattern FrontController Abstract Factory Service Locator Factory Method Session Facade Business Delegate Chain of Responsibility Transfer Object Proxy Data Access Object State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Singleton Ziele Erzeugung einer einzigen applikationsweit gültigen Objektinstanz Klassische Realisierung in Java public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getIntance() { return instance; } } 43 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Singleton - Relevanz Notwendig in allen Schichten PersistenceManager, DataSource,… Aber: Keine Notwendigkeit für static, stattdessen Web Tier Application Context Business/Integration Tier Spring-managed Singletons <bean id=“myBean“ class=“myClass“ /> State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Factory Ziele Erzeugung von Familien zusammenhängender Objekte Unabhängigkeit von konkreten Implementierungen Klassische Realisierung in Java package java.awt; public abstract class Toolkit { public static synchronized Toolkit getDefaultToolkit() { ... } public abstract ButtonBeer createButton(Button button); public abstract TextFieldPeer createTextField(TextField field); … } 44 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Factory - Relevanz Selten bis gar nicht notwendig durch Einsatz von IoC Vorraussetzung: Objekt ist Spring-Managed Gegebenenfalls Einsatz im Domain Modell Beispiel: Zusammenstellung von Angeboten (Alternative Builder Pattern) State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Chain of Responsibility Ziele Mehrstufige Verarbeitung eines Objektes („Commands“) Lose Kopplung zum Verarbeitungsziel, State ist Kommunikationsmedium Klassische Realisierung in Java 45 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Chain of Responsibility Ziele Mehrstufige Verarbeitung eines Objektes („Commands“) Lose Kopplung zum Verarbeitungsziel, State ist Kommunikationsmedium Klassische Realisierung in Java public interface LogHandler { public void log(LogEvent event); } public class FileLogHandler implements LogHandler { public void log(LogEvent event) { // Log event to file … // Proceed in chain event.procceed(); } } public class ConsoleLogHandler implements LogHandler { … } State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Chain of Responsibility - Relevanz Zentrales Design Pattern aktueller Java Frameworks Auch bekannt unter Interceptor/ Interceptor Chain Daher: Implizite Nutzung durch Spring/Hibernate Presentation Tier JSF Event Verarbeitung … Business Tier Deklarative Transaktionen oder Security … Persistence Tier Persistence Callbacks/ Event Handler … 46 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Proxy Ziele Erzeugung eines „Stellvertreters“ für ein konkretes Objekt „Zwischenschaltung“ von client-neutraler Behavior Klassische Realisierung in Java State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Proxy Ziele Erzeugung eines „Stellvertreters“ für ein konkretes Objekt „Zwischenschaltung“ von client-neutraler Behavior Klassische Realisierung in Java public interface OrderService { public Order placeOrder(Offer offer); } public class PerformanceMonitor implements InvocationHandler { private OrderService target; public PerformanceMonitor(OrderService aTarget) { target = aTarget; } public Object invoke(Object proxy, Method method, Object[] args) … { long time = System.currentTimeMilis(); try { return method.invoke(target, args); } finally { System.out.println("Elapsed " + …); } } 47 State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Proxy Ziele Erzeugung eines „Stellvertreters“ für ein konkretes Objekt „Zwischenschaltung“ von client-neutraler Behavior Klassische Realisierung in Java // manually creating a proxy OrderService original = …; PerformanceMonitor performanceMonitor = new PerformanceMonitor(original); OrderService proxied = Proxy.newProxyInstance( classLoader, new Class[]{OrderService.class}, performanceMonitor); proxied.placeOrder(…); State-of-the-Art Enterprise Java / Know-How Check GOF Pattern Proxy - Relevanz Zentrales Design Pattern aktueller Java Frameworks Daher: Implizite Nutzung durch Spring/Hibernate Presentation Tier JSF <-> Spring Übergang Business Tier Deklarative Transaktionen Zirkulare Abhängigkeiten … Persistence Tier Lazy Loading von Relationen Zirkulare Abhängigkeiten … 48 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern FrontController Ziele zentralisierter Zugriffspunkt für das Request-Handling in der Präsentationsschicht Requestdispatching, Authentifizierung, Autorisierung,… Klassische Realisierung in J2EE 1.4 // ein einfacher FrontController public class FrontController extends HttpServlet { protected void service(HttpServletRequest req, HttpServletResponse resp) { // process all … } } State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern FrontController Ziele zentralisierter Zugriffspunkt für das Request-Handling in der Präsentationsschicht Requestdispatching, Authentifizierung, Autorisierung,… Klassische Realisierung in J2EE 1.4 <!-- web.xml Ausschnitt --> <web> <servlet> <servlet-name>FrontController</servlet-name> <servlet-class>oop2008.FrontController</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>FrontController</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web> 49 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern FrontController - Relevanz Grundlage eines jeden Web Frameworks Daher: Implizite Nutzung durch JSF State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Intercepting Filter Ziele Filterung von HTTP Requests zur Einführung von allgemeingültigem Verhalten Entspricht weitestgehend Chain of Responsibility Klassische Realisierung in J2EE 1.4 public class DebugFilter implements Filter { public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain){ try { debugRequest(request); chain.doFilter(); } finally { debugResponse(response); } } } 50 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Intercepting Filter - Relevanz Sonderfall Interceptor (Chain of Responsibility) Bestandteil Java EE (Servlet API) State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Service Locator Ziele Abstraktion des Service Lookups von der Service Registry Primär für JNDI Lookup Klassische Realisierung in J2EE 1.4 public class ServiceLocator { public static Object getService(String name) { InitialContext ctx = new InitialContext(); try { return ctx.lookup(name); } finally { ctx.close(); } } } Ohne Exception Handling 51 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Service Locator - Relevanz ServiceLookup und „Wiring“ Aufgabe des IoC Containers <bean name=“myBean“ class=“foo.myBean"> <property name="userService" ref="userService"/> <property name="preferences" ref="preferences"/> </bean> Daher Keine Relevanz in aktuellen IoC Architekturen Aber Implizite Nutzung beim Übergang Presentation Tier zu Business Tier State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Session Façade Ziele Verringerung der Interaktionen zwischen Business-Objekten für Remote-APIs Nutzung eines Session Beans als Facade Klassische Realisierung in J2EE 1.4 public interface OrderManager extends EJBObject { public Order createOrder(Offer offer) throws InvalidXXException; } 52 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Session Façade Ziele Verringerung der Interaktionen zwischen Business-Objekten für Remote-APIs Nutzung eines Session Beans als Facade Klassische Realisierung in J2EE 1.4 public class OrderManagerBean implements SessionBean { public Order createOrder(Offer offer) throws InvalidXXException { if (getCatalogBean().validate(offer)) { Order order = getOrderBean().createOrder(offer); getCartBean().remove(offer); return order; } throw new InvalidXXException(); } … } State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Session Façade - Relevanz Façade ist klassisches GOF Pattern Presentation Tier: Controller Business Tier: Services Remoting Aspekt spielt untergeordnete Rolle Bewusster Einsatz statt Infrastruktur Diktat Daher: Session Façade keine Relevanz Stattdessen einfache Java SE Façade und gegebenenfalls Proxy 53 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Business Delegate Ziele Einführung eines neutralen „Ansprechpartners“ für Clients Kapselung infrastruktureller Details wie Lookup und Remoting Klassische Realisierung in J2EE 1.4 public class OrderBusinessDelegate { public OrderStatus getOrderStatus(String orderId) throws UnknownOrderExeption, OrderFacadeException { try { RemoteOrderEjb ejb = (RemoteOrderEjb) ServiceLocator.getService(OrderEjb.class); return ejb.getOrderStatus(orderId); } catch throw } catch throw } (NamingException e) { new OrderFacadeException(e); (RemoteException e) { new OrderFacadeException(e); } State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Business Delegate - Relevanz Business Delegate ist ein Ergebnis infrastruktureller Probleme der J2EE <= 1.4 Plattform Keine Unterscheidung zwischen Remote/Local ServiceLocator ist obsolete In heutigen Architekturen keine Relevanz Stattdessen: Nutzung der Wiring Fähigkeiten moderner IoC Container Für weiterführende Anforderungen Einsatz des Proxy Pattern 54 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Transfer Object Ziele Grobgranularer Datenaustausch zwischen Schichten über spezielle Objekte Klassische Realisierung in J2EE 1.4 public class OfferPackage { private HotelOffer hotelOffers; private FlightOffer flightOffers; private RentalCarOffer rentalCarOffer; private Money packagePrice; private Money originalPrice; // lots of getter/setter methods } State-of-the-Art Enterprise Java / Know-How Check J2EE Pattern Transfer Object - Relevanz TransferObjects sind ein Ergebnis infrastruktureller Probleme der J2EE <= 1.4 Plattform In heutigen Architekturen keine Relevanz Stattdessen: Nutzung eines reichen Domain Modells inklusive Persistenz Einführung von Tabulardata Objekten für Reporting 55 State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Data Access Object Ziele Abstraktion der Datenquelle Relationale Datenbank, LDAP … Klassische Realisierung in J2EE 1.4 public interface OrderDao { public List<Orders> findOrdersByCustomer(…); public Order findOrderById(String id); public void storeOrder(Order order); … } State-of-the-Art Enterprise Java / Know-How Check J2EE 1.4 Pattern Data Access Object - Relevanz Notwendigkeit der Abstraktion des Datenzugriffs abhängig von Anforderungen Datenbankspezifische Abstraktion durch O/R Mapper unnötig Aber: Erleichtert Testbarkeit durch Einführung einer austauschbaren Integrationskomponente 56 State-of-the-Art Enterprise Java / Know-How Check GOF/J2EE Pattern Fazit Enterprise Java Pattern = Rückbesinnung auf einfache Java Muster Objekte Schnittstellen Abhängigkeiten Gang of Four Pattern haben hohe Relevanz Adaption der Implementation beachten Beispiel Singleton J2EE 1.4 Pattern meist Infrastruktur Muster - kaum Relevanz IoC Infrastruktur übernimmt Aufgabe Defizite der Architektur nicht vorhanden Agenda Enterprise Java - Know-How Check GOF und Java EE Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Unit Testing Integration Testing Enterprise Java - Build Management und Deployment 57 State-of-the-Art Enterprise Java / Know-How Check openTravel Agency: Servicebasierte Architektur Presentation Tier Tiles Templates und JSF Business Tier Controller Feingranulare Business Logik Services Grobgranulare Business Logik Integration Tier Data Access Objects OR Mapping Implementierung Mock Implementierung Wiring und Construction Spring Framework State-of-the-Art Enterprise Java / Know-How Check openTravel Agency: Servicebasierte Architektur 58 Agenda Enterprise Java - Know-How Check GOF und Java EE Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise Java - Build Management und Deployment State-of-the-Art Enterprise Java / Know-How Check Das Modell - ein naiver Ansatz 1. Modellierung des Domain Modells in Java Beziehungen, Ableitungen etc. 2. Persistence Binding über O/R Mapper Hibernate Xdoclet Tags oder JPA Annotationen 3. Automatisches Erzeugen des statischen Datenmodells durch O/R Mapper 59 State-of-the-Art Enterprise Java / Know-How Check Das Modell - ein naiver Ansatz State-of-the-Art Enterprise Java / Know-How Check Das Modell - ein naiver Ansatz 60 State-of-the-Art Enterprise Java / Know-How Check Abgrenzung Modelle Statisches Datenmodell Weitestgehend applikationsneutrale Datenhaltung in einem persistenten Medium Java Objekt Modell Applikationsspezifisches Objektmodell, repräsentiert Fachlichkeit UI Modell Userinterfacenahes Modell zur Abbildung von Formulardaten Zumeist Aggregationen plus State State-of-the-Art Enterprise Java / Know-How Check Best Practices Umsetzung Modelle Vorgehensmodell 1. Erstellung eines Domain Modells zur Abbildung der Fachlichkeit 2. Iterativ Modellierung statisches Datenmodell Datenbank Modellierung Objektmodell Java Umsetzung O/R Mapping 3. Ergänzung des Modells um Nicht persistente Aggregationen im Business Tier Service Kommunikation Visualisierungsnahe Aggregationen im UI Tier Formulardaten Bitte nicht! Generierung des statischen Datenmodells auf der Basis des Objekt Modells Generierung eines Persistenzobjektmodells auf der Basis eines statischen Datenmodells 61 Agenda Enterprise Java - Know-How Check GOF und Java EE Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise - Build Management und Deployment State-of-the-Art Enterprise Java / Source Check Das Beispiel… 62 Agenda Enterprise Java - Know-How Check GOF und Java EE Pattern Architekturansatz Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise Java - Build Management und Deployment State-of-the-Art Enterprise Java / Testing Software Test Arten Kompatibilitätstests Funktionale Tests Lasttests Performancetests Regression Tests Unittests … 63 State-of-the-Art Enterprise Java / Testing Software Test Arten Kompatibilitätstests Funktionale Tests Lasttests Performancetests Regression Tests Unittests … State-of-the-Art Enterprise Java / Testing Unit Tests: Spring Managed Beans public interface UserService { public User authenticate(String userName, String password) throws AuthenticationException; … } public class PersistentUserService implements UserService { private UserDao dao; public PersistentUserService(UserDao aDao) { dao = aDao; } public User authenticate(String userName, String password) throws AuthenticationException { … User user = dao.findByUserNameAndPassword(userName, password); … } } 64 State-of-the-Art Enterprise Java / Testing Unit Tests: Spring Managed Beans public void testPersistentUserService() { UserDao userDao = new UserDao() { public User findByUserNameAndPassword( String aUserName, String aPassword) { if ("foo".equals(aUserName) && "bar".equals(aPassword)) { User user = new User(); user.setUserName("foo"); user.setPassword("bar"); user.setLastLoginDate(new Date(0L)); return user; } else { return null; } } … }; UserService service = new PersistentUserService(userDao); User user = service.authenticate("foo", "bar"); assertNotNull(user); assertEquals("foo", user.getUserName()); assertEquals("bar", user.getPassword()); assertTrue(user.getLastLoginDate().getTime() > 0); } State-of-the-Art Enterprise Java / Testing Unit Tests: Spring Managed Beans Vollständig Testbar ohne Container, umfasst Controller Services *Dao Achtung Problemfall Testdaten Vorteil Spring Management von „JSF Managed Beans“ Keine Laufzeit JSF Abhängigkeiten FacesContext 65 State-of-the-Art Enterprise Java / Testing Funktionale Tests Vollständige Tests der Applikation User Interface und Navigation Business und Integration Tier Gegebenenfalls Persistence Store Automatisierungsproblem Web UI Testframeworks weiterhin schwer handhabbar Setup, Konfiguration, Testdaten Entwicklertests Lokales Deployment - dazu gleich mehr Agenda Enterprise Java - Know-How Check GOF und Java EE Pattern Architekturansatz Das Modell Enterprise Java - Source Check Ein Use Case Enterprise Java - Testing Enterprise Java - Build Management und Deployment 66 State-of-the-Art Enterprise Java / Build und Deployment Build und Deployment - Ant Vergleichweise einfaches Build für Enterprise Java Stack <javac destdir="${build.classes.dir}“ classpathref="classpath" source="1.5“ target="1.5“ debug="true“ srcdir="${src.java.dir}"/> <copy todir="${build.classes.dir}" encoding="UTF-8"> <fileset dir="${resources.dir}"/> </copy> <war destfile="${build.dir}/${target.name}.war" webxml="${webapp.dir}/WEB-INF/web.xml"> <fileset dir="${webapp.dir}"> <exclude name="**/web.xml"/> </fileset> <lib dir="${lib.dir}"> <exclude name="**/xdoclet/**"/> </lib> <classes dir="${build.classes.dir}"/> </war> Offene Problembereiche Generierung von Deskriptoren Deployment der Anwendung in Laufzeitumgebung Library Management State-of-the-Art Enterprise Java / Build und Deployment Build und Deployment Alternative - Maven2 Deklaratives Dependency und Build Management <pom> <dependencies> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-api</artifactId> <version>1.1.5</version> </dependency> <dependency> <groupId>org.apache.myfaces.core</groupId> <artifactId>myfaces-impl</artifactId> <version>1.1.5</version> </dependency> … </dependencies> </pom> 67 State-of-the-Art Enterprise Java / Build und Deployment Build und Deployment Alternative - Maven2 Deklaratives Dependency und Build Management <pom> … <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId>maven-jetty-plugin</artifactId> <configuration> <systemProperties> <systemProperty> <name>java.awt.headless</name> <value>true</value> </systemProperty> </systemProperties> </configuration> </plugin> … </pom> State-of-the-Art Enterprise Java / Build und Deployment Beispiel… 68 OOP 2008 - State-of-the-Art Enterprise Java Fazit Verschiedenes Know-How aus der Zeit J2EE 1.4 überholt Aktueller Enterprise Java Stack sehr mächtig Viele Optionen, viele Lösungen, umfassende Dokumentation Ermöglicht kleine Lösungen mit der Option Der Verbreiterung des Entwicklungsteams Für fachliches Wachstum Für Erhöhung der Last und Skalierbarkeitsanforderungen Weiterhin vorhandene Entscheidungskomplexität Frameworkauswahl, Lösungsansatz, Integrationsansatz Aber: Enterprise Java Stack weitestgehend Java SE Komplexität stellt sich einmalig ohne Auswirkung auf Entwicklungsprozess OOP 2008 - State-of-the-Art Enterprise Java Vielen Dank! Lars Röwekamp CIO New Technologies Jens Schumann CTO Development OpenKnowledge GmbH Bismarckstr. 13 26122 Oldenburg Tel.: +49 (441) 40 82 - 0 [email protected] 69