1 Überblick ■ Projekt-Aufbau (in Eclipse) ◆ Verzeichnisstruktur Architekturen für verteilte Internetdienste ◆ Build-Prozess, Launchers ■ Beans ◆ Container-Managed Persistence ◆ Finders, Selectors ◆ Bean-Referenzen Übung 5: Enterprise JavaBeans ■ Deskriptoren ■ Client Projekt-Beispiel ■ Application-Server / Demo ◆ Web-Konsole ◆ Datenbank 5.41 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 2 Projekt-Aufbau 2 Projekt-Aufbau (2) ■ Eclipse als Entwicklungsumgebung ■ Build-Prozess ◆ hier ohne weitere Plugins ◆ Implementierung in Eclipse ◆ Inkrementeller Compiler übersetzt im Hintergrund ■ Verzeichnisstruktur ◆ Erzeugen der IIOP-Stubs für den Client ◆ src/ – Quellcode ◆ Paketierung ◆ bin/ – Launchers, Shellscripts ◆ Deployment ◆ etc/ – Deskriptoren ◆ Client starten ◆ lib/ – J2EE-Bibliothek ◆ src-gen/ – Generierter Quellcode ▲ Server und Datenbank vorher einzeln starten, danach stoppen (s.u.) ◆ avid.ear – Application Archive ■ Launchers ◆ avid-cli.jar – Client Archive ◆ „External Tools“, um Targets im ANT Buildfile zu starten ◆ avid-ejb.jar – Bean Archive ◆ „Java Application Launcher“, um Client in Eclipse zu starten ◆ build.xml – ANT Buildfile 5.42 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.43 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 2 Projekt-Aufbau (3) 2.1 IIOP-Stubs ■ Probleme im Betrieb ■ Mittels Launcher für ANT-Target <target name="stubs"> ◆ Application Server und Datenbank laufen als eigenständige Prozesse <rmic base="classes" iiop="true" classpath="classes:lib/j2ee.jar" classname="avid.u5.TaskControllerHome" /> • Debugging unkomfortabel • Plugins starten sie in Eclipse Debugging-Context ◆ Deployment schlägt fehl… <delete dir="classes/org"/> • Kompletter Eclipse-Build + Refresh + Paketierung </target> • Undeployment • Datenbanktabellen löschen → SQL-Tool ◆ Stubs für org.omg-Klassen werden gelöscht • Deployment erneut versuchen ◆ Stubs für avid.u5.TaskController werden transitiv mitgeneriert • Einzelne Beans deaktivieren, Fehler eingrenzen… ■ Oder per Shellskript rmic -classpath classes:lib/j2ee.jar -d classes -iiop \ avid.u5.TaskControllerHome avid.u5.TaskController 5.44 5.45 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 2.2 Paketierung 2.2 Paketierung (2) ■ Mindestens 2 Archive notwendig ■ Bean Archive (…) ◆ Bean Archive: avid-ejb.jar ◆ ANT-Target ◆ Application Archive: avid.ear <target name="jar" description="avid-ejb.jar"> ◆ Web Archive, Client Archive, … (hier nicht gezeigt) <delete file="avid-ejb.jar"/> ◆ Weitere (hinzugekaufte) Bean Archives mit Programmteilen <jar destfile="avid-ejb.jar" manifest="etc/MANIFEST.MF"> ✱ Aufbau der Archive muss strikt eingehalten werden! <zipfileset dir="etc" prefix="META-INF"> <include name="ejb-jar.xml" /> <include name="sun-ejb-jar.xml" /> </zipfileset> ■ Bean Archive ◆ Unterverzeichnis „META-INF“ <zipfileset dir="classes" includes="**/*.class" excludes="**/www/**/*.*"> <exclude name="avid/u5/Client.class"/> <exclude name="**/_*_Stub.class"/> </zipfileset> </jar> </target> • Bean Descriptor: ejb-jar.xml • Bean Descriptor: sun-ejb-jar.xml (Server-spezifisch) ◆ Unterverzeichnis „classes“ • Bean-Klassen 5.46 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.47 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 2.2 Paketierung (3) 2.2 Paketierung (4) ■ Application Archive ■ Application Archive (…) ◆ ANT-Target ◆ Ebenfalls eine JAR-Datei <target name="ear" description="avid.ear"> ◆ Unterverzeichnis „META-INF“ <delete file="avid.ear"/> • Application Descriptor: application.xml <jar destfile="avid.ear" manifest="etc/MANIFEST.MF"> • Application Descriptor: sun-application.xml (Server-spezifisch) <zipfileset dir="etc" prefix="META-INF"> <include name="application.xml" /> <include name="sun-application.xml" /> </zipfileset> ◆ Wurzelverzeichnis „.“ • Bean Archive • Web Archive, weitere Archive, … (hier nicht notwendig) <zipfileset dir="."> <include name="avid-ejb.jar" /> </zipfileset> </jar> </target> 5.48 5.49 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 2.3 Deployment 2.3 Deployment (2) ■ „Hot/Auto Deployment“ ■ ANT-Targets ◆ Application Archive wird in spezielles Verzeichnis kopiert <target name="sun-deploy"> <copy file="avid.ear" todir="${SunAS}/domains/domain1/autodeploy"/> </target> ◆ Application Server bemerkt und integriert es ◆ Datenbank-Tabellen werden ggf. erzeugt ▲ Datenbank vorher starten! (s.u.) <target name="sun-undeploy"> <delete file="${SunAS}/domains/domain1/autodeploy/avid.ear"/> </target> ■ Server-Logfile beobachten ◆ Fehler in Deskriptoren/Code hier durch Exceptions angezeigt ▲ Ende des Vorgangs abwarten! ■ Undeployment ◆ EAR aus Deployment-Verzeichnis löschen… ◆ Datenbank-Tabellen werden ggf. entfernt 5.50 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.51 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 3 Beans 3.1 Container-Managed Persistence (2) ■ Bean-Interface Themen: CMP, Home-Methods, Finders/Selectors, Bean-Referenzen public interface Task extends EJBObject { 3.1 Container-Managed Persistence public Integer getId() throws RemoteException; public void setId(Integer id) throws RemoteException; ◆ Erzeugen, Löschen von Objekten public String getDescription() ...; public void setDescription(String text) ...; ◆ Autonomes Laden, Sichern der Datenfelder ◆ Integrität von Bean-zu-Bean-Relationen public Date getDue() ...; public void setDue(Date date) ...; ◆ Einhaltung von Konsistenzbedingungen ■ Programmiermodell public boolean getCompleted() ...; public void setCompleted(boolean value) ...; ◆ Abstrakte Methoden → Implementiert in abgeleiteter Klasse des Containers • In der Bean-Klasse public TaskData getData() ...; public void setData(TaskData data) ...; ◆ EJB-QL für Finder/Selectors → Umsetzung in Datenbank-Abfragen } • Im Deployment-Descriptor 5.52 5.53 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 3.1 Container-Managed Persistence (3) 3.1 Container-Managed Persistence (4) ■ Bean-Klasse ■ Bean-Klasse (…) abstract public class TaskBean implements EntityBean { public public public public private static java.util.logging.Logger log = java.util.logging.Logger.getLogger( TaskBean.class.getName()); void void void void ejbActivate() ... {} ejbPassivate() ... {} ejbLoad() ... {} ejbStore() ... {} public void unsetEntityContext() ... { log.info("unset entity context"); this.context = null; } private EntityContext context; public Integer ejbCreate() throws CreateException, RemoteException { log.info("create"); setId(42); return null; // for CMP return null! } public void setEntityContext(EntityContext context) ... { log.info("set entity context"); this.context = context; } public void ejbPostCreate() ... { } ... public void ejbRemove() ... {} ... 5.54 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.55 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 3.1 Container-Managed Persistence (5) 3.1 Container-Managed Persistence (6) ■ Bean-Klasse (…) Home Methods ■ Bean-Klasse (…) Finders, Selectors public int ejbHomeCountTasks() throws RemoteException { try { int c = ejbSelectCountTasks(); return c; } catch(FinderException e) { ... } } abstract public int ejbSelectCountTasks() throws FinderException, RemoteException; abstract public Collection ejbSelectGetTaskIDs() throws FinderException, RemoteException; abstract public Integer ejbFindByPrimaryKey(Integer id) throws FinderException, RemoteException; public int[] ejbHomeGetTaskIDs() throws RemoteException { try { Collection ids = ejbSelectGetTaskIDs(); int[] ida = new int[ids.size()]; int i=0; for (Object o: ids) ida[i++] = (Integer) o; return ida; } catch(FinderException e) { ... } } ... 5.56 5.57 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 3.1 Container-Managed Persistence (7) 3.1 Container-Managed Persistence (8) ■ Bean-Klasse (…) CMP-„Instanzvariablen“, Methoden ■ Bean-Home abstract public Integer getId() throws RemoteException; abstract public void setId(Integer id) throws RemoteException; public interface TaskHome extends EJBHome { public Task create() throws CreateException, RemoteException; abstract public String getDescription() ...; abstract public void setDescription(String text) ...; public int countTasks() throws RemoteException; public int[] getTaskIDs() throws RemoteException; ...weitere Methoden... public Task findByPrimaryKey(Integer id) throws FinderException, RemoteException; public TaskData getData() throws RemoteException { return new TaskData( getDescription(), getDue(), getCompleted() ); } } public void setData(TaskData data) throws RemoteException { setDescription(data.getDescription()); setDue(data.getDue()); setCompleted(data.getCompleted()); } } 5.58 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.59 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 3.2 Home-Methods, Finders, Selectors 3.3 Bean-Referenzen ■ Home-Methods ■ Referenzen zwischen Beans müssen deklariert werden ◆ Als ejbHomeM… im Bean implementiert, im Home deklariert ◆ Um JNDI-Einträge verwalten zu können ◆ Achtung Camel-Case: ejbHomeMethodName() → methodName() ◆ Zur Unterstützung der Koordinierung im Container ■ Finders ■ Varianten ◆ findByPrimaryKey() im Home liefert Bean-Referenz ◆ Innerhalb eines Bean-Archive ◆ abstract ejbFindByPrimaryKey() im Bean liefert PrimaryKey-Objekt ◆ Innerhalb eines Application-Archive ◆ Varianten mit Collection für Ergebnismenge ◆ Zwischen Anwendungen ■ Selectors ähnlich ■ Deskriptor enthält pro Bean <ejb-ref> Elemente ◆ Namenspräfix ejbSelect… ◆ ejb-ref-name benennt lokale Forderung ◆ Ebenfalls abstract, Bean-intern ohne externe Repräsentation im Home ◆ Archiv-lokal: <ejb-link> realisiert Verbindung auf <ejb-name> der Ziel-Bean ✱ EJB-QL zu Finders/Selectors s.u. ◆ Archiv-übergreifend: zusätzlich Abbildung im Application Descriptor • <ejb-ref-name> wird auf (ggf. externes) JNDI-Ziel abgebildet 5.60 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.61 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 4 Deskriptoren 4 Deskriptoren (2) ■ ejb-jar.xml ■ ejb-jar.xml (…) Session TaskController <?xml version="1.0" encoding="UTF-8"?> <enterprise-beans> <!--DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejbjar_2_0.dtd"--> <session> <description/> <display-name>The Task Controller</display-name> <ejb-jar version = "2.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd"> <description/> <display-name>avid implementation</display-name> ... <ejb-name>TaskController</ejb-name> ... <ejb-ref> <description>Reference to the Task entity</description> <ejb-ref-name>ejb/task</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>avid.u5.TaskHome</home> <remote>avid.u5.Task</remote> <ejb-link>Task</ejb-link> </ejb-ref> ... </session> 5.62 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.63 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 4 Deskriptoren (3) 4 Deskriptoren (4) ■ ejb-jar.xml (…) Entity Task ■ ejb-jar.xml (…) Entity Task → ejbFindByPrimaryKey ohne Query! <entity> <ejb-name>Task</ejb-name> ... <home>avid.u5.TaskHome</home> <remote>avid.u5.Task</remote> <ejb-class>avid.u5.TaskBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> ... <cmp-version>2.x</cmp-version> <abstract-schema-name>Task</abstract-schema-name> <cmp-field> <field-name>id</field-name> </cmp-field> <cmp-field> <field-name>description... <cmp-field> <field-name>due... <cmp-field> <field-name>completed... <primkey-field>id</primkey-field> 5.64 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ <query> <description>Count all tasks.</description> <query-method> <method-name>ejbSelectCountTasks</method-name> <method-params/> </query-method> <ejb-ql> <![CDATA[ SELECT COUNT(t) FROM Task as t ]]> </ejb-ql> </query> <query> <description>Get all task IDs</description> <query-method> <method-name>ejbSelectGetTaskIDs</method-name> <method-params/> </query-method> <ejb-ql><![CDATA[ SELECT t.id FROM Task as t ]]></ejb-ql> </query> </entity> </enterprise-beans> 5.65 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 4 Deskriptoren (5) 4 Deskriptoren (6) ■ ejb-jar.xml (…) ■ sun-ejb-jar.xml (in Auszügen!) <assembly-descriptor> <container-transaction> <method> <ejb-name>Task</ejb-name> <method-intf>Remote</method-intf> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> 5.66 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ <sun-ejb-jar> <enterprise-beans> <ejb> <ejb-name>Task</ejb-name> <jndi-name>ejb/task</jndi-name> <cmp/> <is-read-only-bean>false</is-read-only-bean> <gen-classes/> </ejb> <cmp-resource> <jndi-name>jdbc/__default</jndi-name> <default-resource-principal> <name>APP</name> <password>APP</password> </default-resource-principal> <create-tables-at-deploy>true</create-tables-at-deploy> <drop-tables-at-undeploy>true</drop-tables-at-undeploy> <database-vendor-name>derby</database-vendor-name> </cmp-resource> </enterprise-beans> </sun-ejb-jar> 5.67 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5 Client (in Auszügen!) 6 Application-Server ■ Erzeugt einen Task mit ID=42, listet Tasks auf, löscht Task 42 wieder ■ Getrennte Launchers/ANT-Targets für Server und DB Context env= new InitialContext(icenv); // kein "java:comp/env" ! Object tch_ = env.lookup("ejb/taskctrl"); TaskControllerHome tch = (TaskControllerHome) PortableRemoteObject.narrow(tch_, TaskControllerHome.class); TaskController tc = tch.create(); int TID = tc.createTask("...", Calendar.getInstance().getTime()); ◆ Application Server <target name="sun-start"> <exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}"> <arg value="start-domain"/> <arg value="domain1"/> </exec> </target> <target name="sun-stop"> <exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}"> <arg value="stop-domain"/> <arg value="domain1"/> </exec> </target> out.println("Listing "+tc.countTasks()+" tasks:"); for (int id: tc.getTaskIDs()) { TaskData td = tc.getTaskData(id); out.println("\nTask "+id+": "+td.getDue()); tc.deleteTask(TID); tc.remove(); tc=null; tch=null; ◆ TaskController.createTask() erneut möglich? 5.68 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.69 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 6 Application-Server (2) 7 Aufgaben ■ Getrennte Launchers/ANT-Targets für Server und DB (…) ■ Diff der Übungsaufgaben zu EJB studieren ◆ Datenbank ◆ Stateless Session Bean mit Hash (Demo aus Vorlesung) <target name="sun-db-start"> <exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}"> <arg value="start-database"/> </exec> </target> <target name="sun-db-stop"> <exec executable="${SunAS}/bin/asadmin${sfx}" dir="${SunAS}"> <arg value="stop-database"/> </exec> </target> ◆ Entity mit Container-Managed Persistence (dieses Projekt) ◆ In Eclipse: beide Projekte markieren, Mouse: [Compare With, Each Other…] ■ Beispiel ausbauen ◆ Team.ejbCreate() um Parameter erweitern ◆ Team.id automatisch erzeugen, inkrementieren ■ Web-Client ◆ Servlets, JSP, JSF benutzen ▲ Arbeitsverzeichnis im Attribut „dir“ muss korrekt gesetzt sein, da Dateien der Datenbank sonst falsch abgelegt! ◆ Benutzer-Login ◆ TeamController als Stateful Session Bean notwendig! ■ Integrierte Datenbank „Apache-Derby“ ◆ JDBC-URL: „jdbc:derby://localhost/sun-appserv-samples;create“ 5.70 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/ 5.71 © 2006, Andreas I. Schmied, Verteilte Systeme, Univ. Ulm, [2006s-AvID-U5-Projekt.fm, 2006-06-28 11.21] http://www-vs.informatik.uni-ulm.de/teach/ss06/avid/