Enterprise Java Beans

Werbung
Realisierung verteilter Anwendungen: Teil 6
Ralf Möller, FH-Wedel
Beim vorigen Mal:
Einführung in Multitier-Architekturen
Dynamische Seitengenerierung (JSP und Servlets)
Inhalt heute
Komponentenarchitekturen (am Beispiel von Enterprise
Java Beans)
Lernziel:
Grundverständnis des Designs der EJB-Architektur
zur weiteren Vertiefung im Beruf
Enterprise Java Beans (EJB)
Teile von einigen der nachfolgenden Folien wurden übernommen aus:
VL Anwendungssysteme
Gerald Weber
Ziele der EJB-Architektur
Standard-Applikationsserver-Architektur für Java
Abstraktion von Low-Level Aufgaben bei
Transaktionen, Multithreading, Connection Pooling
Komponenten-Orientierung: Applikationen können
aus Teilen verschiedener Hersteller aufgebaut
werden
Definierte Rollenverteilung für die Systemerstellung
Definition der Aufgaben der Rollen durch Contracts
EJB-Architektur
EJB-Server
RMI
Clients
RDBMS
B
JDBC
Container
B
CORBA
LegacyApplication
Beispiel: E-Commerce-System
 Bean-Provider Cat.com
bietet Produktkatalog
MyCat an
 App. Assembler WebVend
erstellt Applikation BuyMe
 Marktplatz GoodStuff ist
Deployer, EJBServer und
Container kommen von
MegaBeans
MyCat
.jar
JSP
DD
.jar
Client
Client
Client
HTTP
EJB
Serv.+
Cont.
Cart
MyCat
Order
M.
C. O.
DD = Deployment Descriptor
JMS (Java Message Service)
JNDI (Java Naming and Directory Interface)
EJB Rollen
Bean Provider (Experte im Anwendungsbereich)
Application Assembler: (Experte im
Anwendungsbereich)
Deployer (Experte für spezielle Systemumgebung)
EJB Server Experte (TP-Experte, z.B. DB-Anbieter)
EJB Container Provider (Experte für Systemprogrammierung, Load Balancing)
System-Administrator
Welche Analyse-Klassen stellen EJBs dar?
EJBs repräsentieren grobkörnige Objekte:
Sitzungsobjekte: Session Beans
Stateless: single-use service, haben keinen Zustand
Stateful: speichern Zustand, aber nur transient
Persistente Objekte: Entity Beans
Beispiel: Eirichtung einer Bean für eine Rechnung,
aber nicht für einen Rechnungsposten
Komponentenbegriff
Beans implementieren Business-Logik.
Beans sind verteilte Objekte.
Bean ist über eine Anzahl von Parametern
anpaßbar.
Beans enthalten deklarative Informationen über
den Einsatzkontext (Deployment-Descriptor).
Client-Zugriff erfolgt durch festgelegte
Interfaces
Java-Sprachebene: Elemente einer EJBean
 Home Interface: Feste Arten
von Klassen-Methoden. U.a.
Life-cycle-Management
Methoden (Erzeugung...)
 Remote Interface:
Instanzmethoden, BusinessMethoden
 Beanklasse: Implementiert
beide Interfaces
 Deployment Descriptor
 Verwendete andere Klassen
(Helper Classes)
Home
Remote
Bean
Helper Helper
Beispiel: Die EntityBean MyCat
 Home-Interface
MyCatHome:
create(String Name)
findByPrimaryKey(String)
findLike(String keyword)
 Remote-Interface MyCat:
getPrice() etc.
setPrice() etc.
buy(int pieces)
 Bean-Klasse MyCatBean:
Implementiert Methoden
aus MyCatHome und
MyCat.
 Deployment Descriptor:
type: entity
role admin: Alle Methoden
role customer: nicht
setPrice().
Locating a (session) Bean’s home interface
JNDI (Java Naming and Directory Interface)
Context initialContext = new InitialContext();
BankBeanHome myBeanHome = (BankBeanHome)
initialContext.lookup("Systems/gsj21/Repository/Applicat
ions/BankExample1/Homes/BankSessionBean");
EJB Contracts: Client-View-Contract
Client kann durch RMI auf Bean zugreifen.
Pro Deployment einer Bean ist ein HomeInterface-Objekt in JNDI eingetragen und für
den Client nutzbar.
Bean Instanzen implementieren das RemoteInterface Der Client erhält sie durch das HomeInterface.
Component Contract
 Beans werden in Container eingebettet
 Bean implementiert Business-M., Life-cycle-M. u.a. Callbacks.
Container ruft diese sinngemäß auf
 Container behandelt z.B. Transaktionen,
Security und Exceptions
 Container bietet JNDI-Environment, EJBContext
 Bean Provider vermeidet Programmierung, die das Container
Runtime Management stört
 Optional: Container behandelt Persistenz
 Deployment-Descriptor enthält entsp. Daten
Motivation der J2EE-Umgebungseinbettung
Beispiel: Verbindungen (connections)
Verbindungsobjekte repräsentieren eine
Zugriffsmöglichkeit auf eine Ressource (z.B. JDBC)
Nachteile des häufigen Verbindungsaufbaus
Auf- und Abbau einer Verbindung ist aufwendig
Bei häufigem Zugriff entsteht großer Overhead
Häufig gilt: mehrere Komponenten greifen auf die
gleiche Ressource zu
Wünschenswert: Pool von Verbindungen für
mehrere Komponenten jeweils für eine Ressource
Beispiel: JDBC-Verbindungen
 Connection con;
 ResultSet results;
 try {
con = DriverManager.getConnection(
"jdbc:odbc://vodka.fh-wedel.de/Db",
username,
password);
results = con.createStatement().executeQuery("...")
 } catch (Exception e) {
System.out.println(e); }
 con.close();
Kontextabhängigkeit des DB-Treibers
try {
Class.forName("org.gjt.mm.mysql.Driver")
} catch (ClassNotFoundException cnfe) {
System.out.println("Cannot load driver");
}
Aber: der Treiber hängt von der Umgebung ab!
Bei Einhaltung des Komponentengedankens muß der
Treibername zur Laufzeit erfragt werden!
Hierzu dient ein Kontextobjekt (sog. EJB-Kontext)
Verbindungen im EJB-Kontext (ohne Pool)
import java.sql.*; import javax.sql.*;
public class AccountBean implements EntityBean {
public Collection ejbFindByLastName(String lName) {
try {
String dbdriver = new
InitialContext().lookup("java:comp/env/DBDRIVER").toString();
Class.forName(dbdriver).newInstance();
Connection conn =
DriverManager.getConnection("java:comp/env/DBURL",
"userID", "password");
<body>
conn.close();
}}
Reduzierung des Aufwandes
Im Applikationsserver laufen viele EJBs
Jede EJB führt kurze Interaktion mit DB durch ...
... und meldet die Verbindung gleich wieder ab
Idee: Teilung von Verbindungen zwischen mehreren
EJBs und mehreren Aufrufen von EJB-Methoden
Notwendig: Verwaltung eines kritischen Abschnitt
(bedingt durch Multithreading) und ggf.
Transaktionsmanagement
Soll das jeder EJB-Programmierer selbst machen?
Connection Pooling durch Container
Idee: Connection Pooling wird durch Umgebung
(container) für alls EJBs übernommen
Verbindungen im EJB-Context (mit Pool) (1)
import java.sql.*;
import javax.sql.*;
// import here vendor-specific JDBC drivers
public ProductPK ejbCreate() {
try {
// initialize JNDI lookup parameters
Context ctx = new InitialContext(...);
...
// Following params could come from a JNDI look-up
ConnectionPoolDataSource cpds =
(ConnectionPoolDataSource)ctx.lookup(cpsource);
Verbindungen im EJB-Context (mit Pool) (2)
...
cpds.setDatabaseName("PTDB");
cpds.setUserIF("XYZ");
PooledConnection pc = cpds.getPooledConnection();
Connection conn = pc.getConnection();
// do business logic
conn.close();
}
...
}
Zusammenfassung der Motivation für J2EE
 Es gibt Aspekte der
Anwendungsprogrammierung, die
für alle Softwarekomponenten
relevant sind
 Es ist sinnvoll, sie nur einmal zu
programmieren und von für
verschiedene Komponenten zu
nutzen
 Es gibt bestimmte Abhängigkeiten
der Komponenten vom konkreten
Einsatzkontext
Eine Beispielanwendung
 Benutzer macht Eingaben in HTML-Formular
 Das ausgefüllte Formular wird durch ein Servlet
verarbeitet
 Das Servlet lokalisiert die Verarbeitungskomponente
(Session Bean) über JNDI (Java Naming and Directory
Service)
 Session Bean macht Berechnung
 Servlet kommuniziert Ergebnis zum Benutzer
J2EE Software und Setup
 Java 2 SDK Enterprise Edition (J2EE),
Version 1.2.1
(http://java.sun.com/j2ee/download.html)
 Java 2 SDK, Standard Edition (J2SE)
Version 1.2 oder neuer
(http://java.sun.com/jdk/index.html).
 Annahme: installiert in $HOME/J2EE/j2sdkee1.2.1
 bzw. $HOME/J2EE/jdk1.2.2
 PATH: $HOME/J2EE/jdk1.2.2/bin und
$HOME/J2EE/j2sdkee1.2.1/bin
 CLASSPATH: $HOME/J2EE/j2sdkee1.2.1/lib/j2ee.jar
J2EE Application Components
Application client components
Enterprise JavaBeans components
Servlets and JavaServer Pages components (auch
Web components genannts)
Applets
J2EE Application Components
Servlet mit HTML-Dateien werden zu einem Web
Archive (WAR) zusammengefaßt
Session Bean und Klassen zu einem JAR Archiv
zusammengefaßt
Enterprise Archive (EAR) Datei zur Verifikation,
zum Testen und zum Deployment in die
Produktionsumgebung enthält alle Teil-Archive
Erzeugen der HTML-Seite bonus.html
Der HTML-Code in .../J2EE/ClientCode
<HTML>
<BODY BGCOLOR = "WHITE"> <BLOCKQUOTE>
<H3>Bonus Calculation</H3>
<FORM METHOD="GET" ACTION="BonusServlet">
<P> Enter social security Number:
<P> <INPUT TYPE="TEXT" NAME="SOCSEC"></INPUT>
<P> Enter Multiplier:
<P> <INPUT TYPE="TEXT" NAME="MULTIPLIER"></INPUT>
<P> <INPUT TYPE="SUBMIT" VALUE="Submit">
<INPUT TYPE="RESET">
</FORM> </BLOCKQUOTE>
</BODY>
</HTML>
Das Servlet
Retrieves the user data
Looks up the session bean
Passes the data to the session bean
Upon receiving a value back from the session
bean, creates an HTML page to display the
returned value to the user
Datei in
.../J2EE/ClientCode/BonusServlet.java
Initialisierungsmethode für Servlet
public class BonusServlet extends HttpServlet {
CalcHome homecalc;
public void init(ServletConfig config)
throws ServletException{
//Look up home interface
try{
InitialContext ctx = new InitialContext();
Object objref = ctx.lookup("calcs");
homecalc =
(CalcHome)PortableRemoteObject.narrow
(objref, CalcHome.class);
... }}
doGet Methode
Eingabe: request und response Objekt
Requests repräsentieren die Eingabe vom Browser
Responses repräsentieren einen Ausgabekanal
zum Browser
Aufgaben:
Finden des Home-Interfaces des Anwendungsobjekts
Aufruf der Methode calcBonus
Generieren des Antwort-HTML-Seite
doGet Methode (Ausschnitt)
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String socsec = null;
int multiplier = 0;
double calc = 0.0;
PrintWriter out;
response.setContentType("text/html");
String title = "EJB Example";
out = response.getWriter();
out.println("<HTML><HEAD><TITLE>")
out.println(title);
out.println("</TITLE></HEAD><BODY>");
doGet Methode (Ausschnitt)
try{
Calc theCalculation;
//Retrieve Bonus and Social Security Information
String strMult = request.getParameter("MULTIPLIER");
Integer integerMult = new Integer(strMult);
multiplier = integerMult.intValue();
socsec = request.getParameter("SOCSEC");
//Calculate bonus
double bonus = 100.00;
theCalculation = homecalc.create();
calc = theCalculation.calcBonus(multiplier, bonus);
} catch(Exception CreateException){
CreateException.printStackTrace();
}
doGet Methode (Ausschnitt)
//Display Data
out.println("<H1>Bonus Calculation</H1>");
out.println("<P>Soc Sec: " + socsec);
out.println("<P>Multiplier: " +
multiplier);
out.println("<P>Bonus Amount: " + calc);
out.println("</BODY></HTML>");
out.close();
}
Erstellung der Session Bean
Zustandlose Bean reicht aus
CalcBean.java
Calc.java
CalcHome.java
in .../J2EE/Beans
CalcHome
package Beans;
import java.rmi.RemoteException;
import javax.ejb.CreateException;
import javax.ejb.EJBHome;
public interface CalcHome
extends EJBHome {
Calc create()
throws CreateException,
RemoteException;
}
Calc Remote Interface
package Beans;
import javax.ejb.EJBObject;
import java.rmi.RemoteException;
public interface Calc extends EJBObject {
public double calcBonus(int multiplier,
double bonus)
throws RemoteException;
}
CalcBean (Ausschnitt)
public class CalcBean implements SessionBean {
public double calcBonus(int multiplier, double bonus) {
double calc = (multiplier*bonus);
return calc;
}
public void ejbCreate() { }
public void setSessionContext(SessionContext ctx) { }
public void ejbRemove() { }
public void ejbActivate() { }
public void ejbPassivate() { }
public void ejbLoad() { }
public void ejbStore() { }
}
Übersetzung von Session Bean und Servel
#!/bin/sh
cd .../J2EE
J2EE_HOME=.../J2EE/j2sdkee1.2.1
CPATH=.:$J2EE_HOME/lib/j2ee.jar
javac -d . -classpath "$CPATH" Beans/CalcBean.java
Beans/CalcHome.java Beans/Calc.java
cd .../J2EE/ClientCode
J2EE_HOME=.../J2EE/j2sdkee1.2.1
CPATH=.:$J2EE_HOME/lib/j2ee.jar:
/home/monicap/J2EE
javac -d . -classpath "$CPATH" BonusServlet.java
Starten des Applikationsservers
j2sdkee1.2.1/bin/j2ee -verbose
... und des Deploy-Tools
deploytool
Fenster für J2EE Applications und Komponenten
Inspektorfenster für Information über ausgewählte
Applikation oder Komponenten
Server-Informationsfenster für installierte
Applikationen
Deploy-Tool
Zusammenbau der Applikation
Erzeugen eines J2EE-Applikation (BonusApp.ear).
Erzeugen einer Enterprise Bean (CalcBean.jar).
Erzeugen einer Web Komponente (Bonus.war).
Angabe eines JNDI Names für die Enterprise
bean (calcs).
Angabe eines sog. Root Context für die J2EEApplikation (BonusRoot).
Enterprise Bean
Web Komponente
JNDI-Eintrag und Root Context
Verifikation und Deployment der Applikation
Start der Applikation
Annahme : Web-Server verwendet Port 8000
(ggf. Konfigurierung in .../J2EE/j2sdkee1.2/config)
Eingabe der URL
http://localhost:8000/BonusRoot/bonus.html
in einem Brower
Ausgabe erfolgt in neuer HTML-Seite
Bonus Calculation
Soc Sec: 777777777
Multiplier: 25
Bonus Amount 2500.0
Diskussion
 Die EJB-Architektur befindet sich zur Zeit in der
Entwicklung
 Es wurde in dieser Vorlesung ein grober Eindruck der
Ziele und wesentlichen Ideen vermittelt, und ...
 es wurden die grundlegenden Entwicklungsschritte für
einer N-Tier-Anwendung erläutert
Und beim nächsten Mal:
Transaktionsmanagement
Security
Persistenz
und eventuell etwas über Lastverteilung
(load balancing)
Herunterladen