Realisierung verteilter Anwendungen: Teil 6 zBeim vorigen Mal: yEinführung in...

Post on 06-Apr-2016

216 views 0 download

Transcript of Realisierung verteilter Anwendungen: Teil 6 zBeim vorigen Mal: yEinführung in...

Realisierung verteilter Anwendungen: Teil 6

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

Ralf Möller, FH-Wedel

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 JavaAbstraktion von Low-Level Aufgaben bei

Transaktionen, Multithreading, Connection PoolingKomponenten-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

RMI

EJB-Server

Clients

RDBMS

CORBA

JDBC

Container

Legacy-Application

B

B

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

MyCat.jar Order

CartJSP

M.O.C.

EJBServ.+Cont.

HTTPClientClient

Client

DD

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 System-

programmierung, 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 BeansBeispiel: 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, Business-Methoden

Beanklasse: Implementiert beide Interfaces

Deployment Descriptor Verwendete andere Klassen

(Helper Classes)

Home Remote

Bean

HelperHelper

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/Applications/BankExample1/Homes/BankSessionBean");

EJB Contracts: Client-View-Contract

Client kann durch RMI auf Bean zugreifen. Pro Deployment einer Bean ist ein Home-

Interface-Objekt in JNDI eingetragen und für den Client nutzbar.

Bean Instanzen implementieren das Remote-Interface Der Client erhält sie durch das Home-Interface.

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 EJBsJede EJB führt kurze Interaktion mit DB durch ...... und meldet die Verbindung gleich wieder abIdee: 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 componentsEnterprise JavaBeans componentsServlets 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 dataLooks up the session beanPasses the data to the session beanUpon 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 ObjektRequests repräsentieren die Eingabe vom

BrowserResponses repräsentieren einen

Ausgabekanal zum BrowserAufgaben:

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 Dataout.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 ausCalcBean.javaCalc.javaCalcHome.javain .../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/shcd .../J2EEJ2EE_HOME=.../J2EE/j2sdkee1.2.1CPATH=.:$J2EE_HOME/lib/j2ee.jarjavac -d . -classpath "$CPATH" Beans/CalcBean.java Beans/CalcHome.java Beans/Calc.java

cd .../J2EE/ClientCodeJ2EE_HOME=.../J2EE/j2sdkee1.2.1CPATH=.:$J2EE_HOME/lib/j2ee.jar:/home/monicap/J2EEjavac -d . -classpath "$CPATH" BonusServlet.java

Starten des Applikationsservers

j2sdkee1.2.1/bin/j2ee -verbose

deploytool Fenster für J2EE Applications und Komponenten Inspektorfenster für Information über ausgewählte

Applikation oder Komponenten Server-Informationsfenster für installierte

Applikationen

... und des Deploy-Tools

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 J2EE-Applikation (BonusRoot).

Enterprise Bean

Web Komponente

JNDI-Eintrag und Root Context

Verifikation und Deployment der Applikation

Start der ApplikationAnnahme : Web-Server verwendet Port 8000

(ggf. Konfigurierung in .../J2EE/j2sdkee1.2/config)Eingabe der URL

http://localhost:8000/BonusRoot/bonus.htmlin 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:

TransaktionsmanagementSecurityPersistenzund eventuell etwas über Lastverteilung

(load balancing)