Komponententechnologien Winter 2014 Komponenten Enterprise Java Beans Übersicht • Java Basics – RTTI und ReflecHon – AnnotaHons – Beans • EJBs (c) Peter Sturm, Uni Trier 1 Komponententechnologien Winter 2014 RTTI UND REFLECTION ReflekHve Programmierung • Run-­‐Time Type InformaHon – Zur Übersetzungszeit • ReflecHon API – Zur Laufzeit (c) Peter Sturm, Uni Trier 2 Komponententechnologien Winter 2014 Beispiel • Generierung einer XML-­‐Beschreibung für eine besHmmte Java-­‐Klasse • Zentrale Anlaufstelle ist die Klasse Class – getDeclaredConstructors • liefert Array aller definierten Konstruktoren – unabhängig von der Sichtbarkeit – getConstructors • liefert Array der sichtbaren Konstruktoren – getDeclaredFields und getFields – getDeclaredMethods und getMethods – ... • Zugriff auf ALLE sprach-­‐relevanten Eigenscha[en eines Typs möglich package syssoft.reflection; import java.io.*; import java.lang.reflect.*; public class TalkAbout { private Class c; public TalkAbout ( Class candidate ) { c = candidate; } public void print ( PrintStream out ) { out.println("<?xml version=\"1.0\" encoding=\"UTF-­‐8\">"); out.println("<class name=\"" + c.getCanonicalName() + "\">"); printConstructors(c.getDeclaredConstructors(),out); printDeclaredFields(c.getDeclaredFields(),out); out.println("</class>"); } private void printConstructors ( Constructor ctors[], PrintStream out ) { for (Constructor ctor : ctors ) { out.println("\t<constructor name=\"" + ctor.getName() + "\" modifiers=\"" + Modifier.toString(ctor.getModifiers()) + "\" >"); printArgumentTypes(ctor.getParameterTypes(),out); out.println("\t</constructor>"); } } private void printDeclaredFields ( Field fields[], PrintStream out ) { for (Field field : fields ) { out.println("\t<field name=\"" + field.getName() + "\" type=\"" + field.getType().toString() + "\" modifiers=\"" + Modifier.toString(field.getModifiers()) + "\" />"); } } private void printArgumentTypes ( Class argts[], PrintStream out ) { for (Class arg : argts) { out.println("\t\t<type name=\"" + arg.getName() + "\" />"); } } Class TalkAbout (c) Peter Sturm, Uni Trier 3 Komponententechnologien Winter 2014 Untersuchte Klasse package syssoft.reflection; public class Candidate { public Candidate ( int x) { this.x = x; } public Candidate () { Reset(); } private int x; public int get_x () { return x; } public void f ( int y, double d ) { if (d < 0) x = y; else x = -­‐y; } protected void Reset () { x = 42; } } Ergibt: <?xml version="1.0" encoding="UTF-­‐8"> <class name="syssoft.reflection.Candidate"> <constructor name="syssoft.reflection.Candidate" modifiers="public" > <type name="int" /> </constructor> <constructor name="syssoft.reflection.Candidate" modifiers="public" > </constructor> <field name="x" type="int" modifiers="private" /> </class> (c) Peter Sturm, Uni Trier 4 Komponententechnologien Winter 2014 ANNOTATIONS Ziele • Anreicherung des Programmcodes • Anwendungsspezifische Erweiterbarkeit • Überprüaarkeit durch Compiler • Auswertung der AnnotaHonen – Verarbeitung der Quellen – Übersetzung – Laufzeit • Scope einer AnnotaHon – Auf welche Elemente eines Typs bezieht sich die AnnotaHon? • Klasse, Interface, Methode, ... • Vergleichbar Aeributen in .NET (c) Peter Sturm, Uni Trier 5 Komponententechnologien Winter 2014 Scope • ElementType RetenHon • Reichweite der AnnotaHon (c) Peter Sturm, Uni Trier 6 Komponententechnologien Winter 2014 Beispiel • Ausgangspunkt TalkAbout (Beispiel ReflecHon) – Methoden können über AnnotaHon um Kommentare erweitert werden, die an entsprechender Stelle in generierten XML-­‐Beschreibung erscheinen sollen • DefiniHon der AnnotaHon Comment package sysso[.annotaHon; import java.lang.annotaHon.*; @Target(ElementType.METHOD) @RetenHon(RetenHonPolicy.RUNTIME) public @interface Comment { String value() default ""; } Verwendung in TalkAbout • Zugang ebenfalls über Klasse Class – getAnnotation oder getAnnotations private void printDeclaredMethods ( Method ms[], PrintStream out ) { for (Method m : ms ) { out.println("\t<method name=\"" + m.getName() + "\" modifiers=\"" + Modifier.toString(m.getModifiers()) + "\" return_type=\"" + m.getReturnType().getName() + "\">"); printArgumentTypes(m.getParameterTypes(),out); Comment c = m.getAnnotaHon(Comment.class); if (c != null) { out.println("\t\t<comment>"); out.println("\t\t\t" + c.value()); out.println("\t\t</comment>"); } out.println("\t</method>"); } } (c) Peter Sturm, Uni Trier 7 Komponententechnologien Winter 2014 Verwendung der AnnotaHon package syssoft.reflection; public class Candidate { public Candidate ( int x) { this.x = x; } public Candidate () { Reset(); } private int x; @Comment("Hier kann man x lesen") public int get_x () { return x; } public void f ( int y, double d ) { if (d < 0) x = y; else x = -­‐y; } protected void Reset () { x = 42; } } Und das Ergebnis ?xml version="1.0" encoding="UTF-­‐8" ?> <class name="syssoft.annotation.Candidate"> <constructor name="syssoft.annotation.Candidate" modifiers="public" > <type name="int" /> </constructor> <constructor name="syssoft.annotation.Candidate" modifiers="public" > </constructor> <field name="x" type="int" modifiers="private" /> <method name="get_x" modifiers="public" return_type="int"> <comment> Hier kann man x lesen </comment> </method> <method name="f" modifiers="public" return_type="void"> <type name="int" /> <type name="double" /> </method> <method name="Reset" modifiers="protected" return_type="void"> </method> </class> (c) Peter Sturm, Uni Trier 8 Komponententechnologien Winter 2014 JAVABEANS JavaBeans • Komponentenbasierte Programmierung in Java • JavaBeans werden in der JVM der Anwendung ausgeführt • JavaBeans sind Komponenten, die – – – – über Zugriffsklassen verfügen besHmmte NamenskonvenHonen bei den Methoden einhalten über Dialogboxen konfigurierbar sind neuen Programmiermethoden (Visual Programming) zugänglich sind • Vergleichbar mit – Controls in OLE, COM, AcHveX (inproc) – Konfiguiermöglichkeiten in Visual Studio (c) Peter Sturm, Uni Trier 9 Komponententechnologien Winter 2014 Die BeanBox • Prototyp einer IDE mit visuellen Programmiereigenscha[en • 4 Fenster – BeanBox: Aktuelle Anwendung – ToolBox: Auflistung aller verfügbaren Beans – ProperHesBox: Eigenscha[en der aktuellen Bean lesen und konfigurieren – MessageTracer Beispiel: JugglerBean (1) • JugglerBean aus Toolbox auswählen und plazieren (c) Peter Sturm, Uni Trier 10 Komponententechnologien Winter 2014 JugglerBean (2) • 2 ExplicitBueon mit „Start“ und „Stop“ hinzufügen JugglerBean (3) • „Stop“: Edit-­‐>Events-­‐>bueon push-­‐>acHonPerformed (c) Peter Sturm, Uni Trier 11 Komponententechnologien Winter 2014 JugglerBean (4) • ... mit JugglerBean verknüpfen JugglerBean (5) • AutomaHsch generierter Code package tmp.sunw.beanbox; import sunw.demo.juggler.Juggler; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; public class ___Hookup_1653fe1423 implements java.awt.event.ActionListener, java.io.Serializable { public void setTarget(sunw.demo.juggler.Juggler t) { target = t; } public void actionPerformed(java.awt.event.ActionEvent arg0) { target.stopJuggling(arg0); } private sunw.demo.juggler.Juggler target; } (c) Peter Sturm, Uni Trier 12 Komponententechnologien Winter 2014 BeanProperHes • BeanBox erkennt ProperHes über Namen der ZugriffsfunkHonen • BeanProperty X – Verwendung sogenannter DecapitalizaHon: • aus setMeineProp bzw. getMeineProp wird meineProp • Angabe der ZugriffsfunkHonen: – public X getX () • Ausnahme: public boolean isX () – public void setX ( X x ) • Nurleseeigenscha[en: Keine setX()-­‐Methode Property-­‐Arten • Simple Property – Variable speichert einen einfachen Wert • Indexed Property – Speicherung eines Feldes – ZugriffsfunkHonen • X[] getX () • void setX ( X[] x) • X getX ( int i ) void setX ( int i, X x ) (c) Peter Sturm, Uni Trier 13 Komponententechnologien Winter 2014 Property-­‐Arten (contd.) • Bound Property – Listener werden über Änderungen informiert – Zusätzlicher ImplemenHerungsaufwand • Bean muß bei Änderung PropertyChange-­‐Event senden • Verwaltung aller Listener: – void addPropertyChangeListener ( ... ) – void removePropertyChangeListener ( ... ) • Convenience-­‐Klasse PropertyChangeSupport vorhanden • Constraint Property – Bound Property mit Vetorecht der Listener Property-­‐Editoren • BeanBox stellt für Grundtypen Editoren zur Verfügung • Editoren für anwendungs-­‐ spezifische Methoden integrierbar (c) Peter Sturm, Uni Trier 14 Komponententechnologien Winter 2014 AlternaHven • BeanBox ist veraltete aber schöne DemonstraHon der wesentlichen Bean-­‐Eigenscha[en – Kleinere InkompaHbilitäten mit neueren Java-­‐Versionen • Neuere Fassung: Bean Builder • Primärer Einsatz: Integrierte Entwicklungsumgebungen – – – – JBuilder NetBeans Eclipse … EJB (c) Peter Sturm, Uni Trier 15 Komponententechnologien Winter 2014 MoHvaHon • Bean = Komponente • Zielgruppe Datenbank – Kommerzielle Anwendungen – E-­‐Commerce • EvoluHon früherer Business Logic – Client/Server-­‐Systeme – TransakHonsmonitore • 3-­‐Tier-­‐ApplikaHonen – Client – Bussiness ApplicaHon – Database Clients Business Objects • Komponenten-­‐basierte Anwendung Datenbank • Varianten – Eigenständige Komponenten – Wrapper für Legacy So[ware – Client-­‐TransakHonen Business Objects • Laufzeitumgebung – EJB Server Business Logic Clients (c) Peter Sturm, Uni Trier 16 Komponententechnologien Winter 2014 Auaau des EJB-­‐Server • Laufzeitumgebung – Namensverwaltung – Anbindung an DB – NachrichtenkommunikaHon Bean Bean • EJB Object = Bean Wrapper Bean – IndirekHonsstufe – Zugriff über ReflecHon • Beantypen – EnHty Bean X Bean EJB Object Bean EJB Object • Zustand, Persistent – Session Bean • Transient • Stateless, Stateful – Message-­‐Driven Beans EJB Server Aufgaben des Servers • Resource Management – Instance Pooling: Beans vorinstanziiert – Instance Swapping: Wechsel der EJB-­‐Object-­‐Bindung – AcHvaHon: SHlllegen und ReakHvieren von Beans • Primary Services – – – – – – (c) Peter Sturm, Uni Trier Concurrency: Single-­‐Threaded Bean-­‐ImplemenHerung TransacHons: ACID-­‐Prinzip Persistence: Container-­‐Managed, Bean-­‐Managed DistribuHon: RMI over JRMP oder RMI-­‐IIOP Naming: JNDI unterstützt LDAP, NIS+, DNS, ... Security: Methodenbasierte Zugriffskontrolle 17 Komponententechnologien Winter 2014 EnHty Beans • RepräsenHeren zustandsbeha[ete Anwendungsobjekte – „Can be expressed as nouns in the business model“ (Burke) • Persistente Speicherung in Datenbank – Abbildung über AnnotaHonen aus Java Persistence SpezifikaHon • EnHty Bean – ist keine Komponente im EJB-­‐Sinn • sondern ein „POJO“ (Plain old Java object) – wird durch Klasse beschrieben – bildet Fields über AnnotaHonen auf Spalten in einer DB-­‐Tabelle ab • AlternaHv über Map-­‐File (XML) – besitzt einen Primärschlüssel – wird von EnHtyManager verwaltet Beispiel Node package syssoft.ejb_graph; import javax.persistence.*; @Entity @Table(name="GRAPH_NODES") public class Node implements java.io.Serializable { private static final long serialVersionUID = 42; private int id; private String name; @Id @Column(name="ID") public int getId() { return id; } public void setId ( int id ) { this.id = id; } @Column(name="NAME") public String getName() { return name; } public void setName ( String name ) { this.name = name; } } (c) Peter Sturm, Uni Trier 18 Komponententechnologien Winter 2014 Beispiel Edge package syssoft.ejb_graph; import javax.persistence.*; @Entity @Table(name="GRAPH_EDGES") public class Edge implements java.io.Serializable { private static final long serialVersionUID = 1L; private int id; private int weight; private int l; private int r; @Id @Column(name="ID") @GeneratedValue public int getId() { return id; } public void setId ( int id ) { this.id = id; } @Column(name="WEIGHT") public int getWeight() { return weight; } public void setWeight ( int weight ) { this.weight = weight; } @Column(name="LEFT") public int getLeft() { return l; } public void setLeft ( int l ) { this.l = l; } @Column(name="RIGHT") public int getRight() { return r; } public void setRight ( int r ) { this.r = r; } } Abbildung auf Datenbank <?xml version="1.0" encoding="UTF-­‐8"?> <persistence> <persistence-­‐unit name="syssoft_graphs"> <jta-­‐data-­‐source>java:/DefaultDS</jta-­‐data-­‐source> <properties> <property name="hibernate.hbm2ddl.auto“ value="create-­‐drop"/> </properties> </persistence-­‐unit> </persistence> • DefaultDS = Standard-­‐DB des jeweiligen ApplicaHon Servers • hibernate.hbm2ddl.auto – AutomaHsche Abbildung der EnHtyBeans auf DB-­‐Tabellen • Create-­‐drop – Tabellen beim Deploy erzeugen und beim Remove wieder löschen (c) Peter Sturm, Uni Trier 19 Komponententechnologien Winter 2014 Stateless Session Bean • Remote-­‐Interface definiert FunkHonalität • Bean-­‐Klasse implemenHert Remote-­‐Interface • PersistenceContext realisiert Zugang zu EnHty Beans Interface GraphRemote package syssoft.ejb_graph; import javax.ejb.*; @Remote public interface GraphRemote { public void createNode ( Node n ); public Node findNode ( int id ); public void connectNodes ( int left_node, int right_node, int weight ); } (c) Peter Sturm, Uni Trier 20 Komponententechnologien Winter 2014 Stateless Session Bean Graph package syssoft.ejb_graph; import javax.ejb.*; import javax.persistence.*; @Stateless public class Graph implements GraphRemote { @PersistenceContext(unitName="syssoft_graphs") private EntityManager em; public void createNode ( Node n ) { em.persist(n); } public Node findNode ( int id ) { return em.find(Node.class, id); } public void connectNodes ( int left, int right, int weight ) { Edge e = new Edge(); e.setWeight(weight); e.setLeft(left); e.setRight(right); em.persist(e); } Stateful Session Beans • Speichern „conversaHonal state“ – Feste Bindung zu jeweils einem Client • Speicherung relevanter ZustandsinformaHon über JNDI-­‐ENC (c) Peter Sturm, Uni Trier 21 Komponententechnologien Winter 2014 Message Driven Beans • Asynchrone KommunikaHon über Nachrichten – Client erwartet keine Antwort – Lebenszyklus der Bean unabhängig von Client-­‐Requests – ImplemenHert kein Remote Interface sondern onMessage (Message m( • Unterstützung für verschiedene Messaging Systeme – Konformität zu JCA 1.5 (J2EE Connector Architecture) • Definiert u.a. auch JDBC Standards • JCA kann auch Java Cryptography Architecture J Mögliche Umsetzung • ApplicaHon Server – – – – – JBoss, Version 4.0.5 jems-­‐Installer für EJB 3.0 StandardinstallaHon Wird später nochmal für Webservices verwendet ;-­‐) Sei JBOSS_HOME das gewählte InstallaHonsverzeichnis • Starten mit JBOSS_HOME/bin/run.sh • Webzugang über hep://localhost:8080 • Verwendung der Default-­‐DB Hypersonic SQL (c) Peter Sturm, Uni Trier 22 Komponententechnologien Winter 2014 Webzugang MBean JNDIView (c) Peter Sturm, Uni Trier 23 Komponententechnologien Winter 2014 Deployment • JAR-­‐File in den Ordner Deploy kopieren – JBoss beobachtet das Verzeichnis konHnuierlich – Einfügen heißt Deploy – Löschen heißt Remove META-­‐INF/MANIFEST.MF syssoft/ syssoft/ejb_graph/ syssoft/ejb_graph/GraphRemote.class syssoft/ejb_graph/Edge.class syssoft/ejb_graph/Graph.class syssoft/ejb_graph/Node.class META-­‐INF/ META-­‐INF/persistence.xml Erfolgreiches Deployment (c) Peter Sturm, Uni Trier 24 Komponententechnologien package syssoft.graph_client; import syssoft.ejb_graph.*; import javax.naming.*; import javax.rmi.*; import java.util.*; public class Client { public static void main(String[] args) { try { Context jndiContext = getInitialContext(); Object ref = jndiContext.lookup("Graph/remote"); GraphRemote graph = (GraphRemote) PortableRemoteObject.narrow(ref, GraphRemote.class); Node n1 = new Node(); n1.setId(1); n1.setName("Knoten 1"); graph.createNode(n1); […] Node n = graph.findNode(2); System.out.println(n.getName() + " found"); } catch (NamingException ne) { System.out.println("Failed to create initial context"); ne.printStackTrace(); } } public static Context getInitialContext () throws NamingException { Properties p = new Properties(); p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); p.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces);"); p.put(Context.PROVIDER_URL, "jnp://localhost:1099"); return new javax.naming.InitialContext(p); } } (c) Peter Sturm, Uni Trier Winter 2014 Client 25 Komponententechnologien Winter 2014 Datenbankinhalt Video (c) Peter Sturm, Uni Trier 26 Komponententechnologien Winter 2014 Stand Videoprojekt (Mai 2008) • Die Bindung über jta-­‐data-­‐source funkHoniert noch nicht • jndiBinding geht ebenfalls noch nicht wie erwartet Andere Meinungen dazu • Ich bin nicht allein J • Es ist häufiger zu hören, daß NetBeans das besser kann! (c) Peter Sturm, Uni Trier 27 Komponententechnologien Winter 2014 Literatur • Bruce Eckel Thinking in Java 4. Auflage, PrenHce Hall • Bill Burke, Richard Monson-­‐Haefel Enterprise JavaBeans 3.0 5. Auflage, O‘Reilly (c) Peter Sturm, Uni Trier 28