wersja do druku - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
wersja do druku - Instytut Informatyki Teoretycznej i Stosowanej
Platforma J2EE i EJB Oprogramowanie systemów równoległych i rozproszonych Wykład 9 Platforma J2EE to zbiór standardów pozwalajacych ˛ budować wielowarstwowe, rozproszone aplikacje. Enterprise JavaBeans (EJB) jest jedna˛ z technologii wchodzacych ˛ w skład J2EE: zawieraja˛ logik˛e biznesowa˛ aplikacji, uruchamiane sa˛ w kontenerze EJB - środowisku uruchomieniowym stanowiacym ˛ cz˛eść serwera aplikacji, Dr inż. Tomasz Olas [email protected] wykorzystywane sa˛ do budowy złożonych aplikacji rozproszonych na zasadzie „składania z klocków”, obsługuje zdalnych i lokalnych klientów, Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛estochowska klientami moga˛ być aplikacje serwlety, JSP, inne EJB. Wykład 9 – p. 1/24 Rola EJB na platformie J2EE Wykład 9 – p Kiedy użyć EJB? W platformie J2EE możemy wyróżnić cztery (pieć) ˛ warstw: klienta, sieciowa, logiki biznesowej, zasobów informacyjnych (warstwa pełniaca ˛ role˛ integracyjna˛ i odpowiadajac ˛ a˛ za współprace˛ z innymi systemami). Nie wszystkie aplikacje J2EE wykorzystuja˛ technologie˛ EJB. Aplikacja musi być skalowalna możliwość rozproszenia komponentów Zaawansowane przetwarzanie transakcyjne kontener oferuje usługi transakcyjne deklaratywne specyfikowanie granic transakcji EJB realizuja˛ logik˛e biznesowa, ˛ zostawiajac ˛ innym elementom aplikacji logik˛e prezentacji. transakcje obiektowe Obsługa różnych typów klientów przegladarka ˛ klient aplikacyjny Wykład 9 – p. 3/24 Wykład 9 – p Rodzaje komponentów EJB Kontener EJB Komponenty EJB pracuja˛ w ramach kontenera EJB, który jest jednym ze składników serwera aplikacyjnego. Kontener EJB pośredniczy w komunikacji pomiedzy ˛ komponentem EJB, a światem zewnetrznym. ˛ Kontener EJB oferuje komponentowi szereg usług o charakterze systemowym: ochrona dostepu, ˛ obsługa transakcji, itp. Komponent EJB może uzyskać dostep ˛ do usług kontenera EJB korzystajac ˛ z mechanizmu typu callback - w chwili powoływania do życia obiektu komponentu EJB, kontener EJB przekazuje komponentowi EJB pewien rodzaj uchwytu zwrotnego - za pomoca˛ tego uchwytu obiekt komponentu EJB może wykonywać wywołania metod kontenera EJB. sesyjny (ang. session) - krótkotrwały obiekt wykorzystywany przez pojedynczego klienta (wykonuje określona˛ operacje˛ wywołana˛ przez klienta), nie sa˛ współdzielone (każdy odpowiada wyłacznie ˛ jednemu klientowi), nie ma charaktru trwałego, encyjny (ang. entity) - reprezentuje pewna˛ jednostk˛e danych, trwale zapisana˛ w systemie baz danych (cz˛esto jest to rekord bazy danych), cechuje sie˛ długim czasem życia, ma charakter trwały, modyfikacje bazy danych realizowane sa˛ w sposób atomowy i transakcyjny, współdzielony przez wielu klientów, dostepnych ˛ dla wielu sesji. sterowane komunikatami (ang. message-driven) - komunikatowy komponent EJB wystepuje ˛ w postaci obiektu nasłuchujacego ˛ w ramach Java Message Service (JMS), uruchamiany wtedy, gdy nadchodzi komunikat od klienta, przetwarzanie komunikatów odbywa sie˛ asynchronicznie, może modyfikować zawartość bazy danych, bezstanowy. Wykład 9 – p. 5/24 Komponenty sesyjne Wykład 9 – p Komponenty encyjne a sesyjne - różnice Istnieja˛ dwie odmiany komponentów sesyjnych: stanowe komponenty sesyjne (ang. stateful) zmienne instancyjne komponentu reprezentuja˛ stan dla konkretnej sesji z klientem, (stan konwersacji), stan kowersacji obejmuje czały czas trwania sesji - przestaje obowiazywać ˛ dopiero w momencie, gdy klient zakończy sesje˛ lub jawnie usunie obiekt. bezstanowe komponenty sesyjne (ang. stateless) nie zapamietuje ˛ stanu konwersacji z klientem, wewnetrzny ˛ stan obiektu jest ważny i spójny tylko podczas pojedynczego wywołania, komponenty bezstanowe, jako jedyne, moga˛ implementować usługi internetowe (Web Services). Wykład 9 – p. 7/24 trwałość - stan komponentu encyjnego jest zapisywany w pamieci ˛ stałej - czas życia znacznie przekraczajacy ˛ okres działania aplikacji. współdzielony dostep ˛ - komponenty encyjne moga˛ być współdzielone przez wielu klientów. Ponieważ każdy z nich może zmienić w tym samym czasie te same wartości ważne jest, aby obiekty encyjne pracowały w ramach transakcji. klucz główny - każdy komponent encyjny posiada unikalny identyfikator zwany kluczem głównym, który pozwala klientowi zlokalizować dokładnie określony komponent. relacje - komponenty encyjne moga˛ tworzyć relacje z innymi obiektami tego typu. Wykład 9 – p Komponenty sterowane komunikatami Trwałość komponentów encyjnych Istnieja˛ dwa sposoby utrwalania danych przez komponenty encyjne: z trwałościa˛ obsługiwana˛ przez komponent (ang. bean-managed) - za zapis i odczyt wartości obiektu z bazy danych odpowiada sam komponent wykorzystujac ˛ do tego celu odpowienie biblioteki np. JDBC czy SQL, z trwałośćia˛ obsługiwana˛ przez kontener EJB (ang. container-managed) - za zapisywanie i odczytywanie stanu komponentu do/z bazy danych odpowiedzialny jest kontener EJB. Wszystkie konieczne metody odwołujace ˛ sie˛ do bazy danych sa˛ automatyczne przez niego generowane. Komponenty sterowane komunikatami pozwalaja˛ aplikacjom J2EE przetwarzać komunikaty w sposób asynchroniczny. Zwykle wystepuj ˛ a˛ one w roli odbiorcy komunikatu JMS, ale również może przetwarzać inne rodzaje wiadomości. Komunikaty wysyłane moga˛ być przez dowolny inny element aplikacji J2EE - program klienta, inny komponent EJB czy też komponent sieciowy. Komunikat może być wysłany również przez aplikacje˛ JMS lub system niekorzystajacy ˛ z infrastruktury J2EE. Najbardziej widoczna różnica pomiedzy ˛ komponentem sterowanym komunikatami a pozostałymi komponentami polega na tym, że klient nie odwołuje sie˛ do komponentu sterowanego komunikatami za pomoca˛ interfejsu. Wykład 9 – p. 9/24 Serwery aplikacji Wykład 9 – p. Ogólny proces tworzenia komponentu EJB Przykładami serwerów Java EE sa: ˛ Przygotowanie kodu źródłowego klasy Java, reprezentujacej ˛ komponent EJB GlassFish (glassfish.dev.java.net), JBOSS (www.jboss.org), Utworzenie dwóch interfejsów Java, reprezentujacych ˛ punkty kontaktu świata zewnetrznego ˛ z komponentem EJB: Sun Java Web Server (www.sun.com), interfejs Home, służacy ˛ do zarzadzania ˛ cyklem życia komponentu EJB BEA Weblogic (www.beasys.com), Borland Visibroker (www.borland.com), interfejs Remote/Local, służacy ˛ do wywoływania metod logiki biznesowej komponentu EJB Caucho Resin (www.caucho.com), IBM WebSphere (www.ibm.com), Przygotowanie XML-owego pliku konfiguracyjnego - deskryptora instalacji (Deployment Descriptor) Jakarta Tomcat (jakarta.apache.org), Oracle Application Server (www.oracle.com), Kompilacja całego przygotowanego kodu Java i utworzenie z niego pliku EJB JAR Orion (www.orionserver.com), W3 Jigsaw (www.w3.org), Umieszczenie przygotowanych plików w systemie plików serwera aplikacji; zarejestrowanie komponentu EJB itd. Wykład 9 – p. 11/24 Wykład 9 – p. Komunikacja pomiedzy ˛ klientem a kontenerem Konwencja nazw komponentów EJB Składnik Składnia Przykład Klasa komponentu <nazwa>Bean KalkulatorBean Interfejs domowy <nazwa>Home KalkulatorHome Interfejs zdalny <nazwa> Kalkulator Lokalny interfejs domowy <nazwa>LocalHome KalkulatorLocalHome Interfejs lokalny <nazwa>Local KalkulatorLocal Wykład 9 – p. 13/24 Wykład 9 – p. Przykład (1/10) Struktura archiwum EJB JAR Interfejs zdalny (Kalkulator): package org.j2eesamples.kalkulator; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Kalkulator extends EJBObject { public double suma(double x1, double x2) throws RemoteException; } Wykład 9 – p. 15/24 Wykład 9 – p. Przykład (2/10) Przykład (3/10) Interfejs domowy (KalkulatorHome): Klasa komponentu EJB (KalkulatorBean): package org.j2eesamples.kalkulator; package org.j2eesamples.kalkulator; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; import javax.ejb.SessionBean; import javax.ejb.SessionContext; public class KalkulatorBean implements SessionBean { public void ejbCreate() {} public void ejbPostCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} public void setSessionContext(SessionContext sc) {} public interface KalkulatorHome extends EJBHome { Kalkulator create() throws RemoteException, CreateException; } public double suma(double x1, double x2) { return x1 + x2; } } Wykład 9 – p. 17/24 Przykład (4/10) Wykład 9 – p. Przykład (5/10) Plik MANIFEST-MF: Plik ejb-jar.xml: Manifest-Version: 1.0 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <ejb-jar> <description>Kalkulator descr</description> <display-name>Kalkulator EJB</display-name> <enterprise-beans> <session> <ejb-name>Kalkulator</ejb-name> <home>org.j2eesamples.kalkulator.KalkulatorHome</home> <remote>org.j2eesamples.kalkulator.Kalkulator</remote> <ejb-class>org.j2eesamples.kalkulator.KalkulatorBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> </session> </enterprise-beans> </ejb-jar> Plik jboss.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 3.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_3_0.dtd"> <jboss> <enterprise-beans> <session> <ejb-name>Kalkulator</ejb-name> <jndi-name>kalkulator/Kalkulator</jndi-name> </session> </enterprise-beans> </jboss> Wykład 9 – p. 19/24 Wykład 9 – p. Przykład (6/10) Przykład (7/10) Instalujemy serwer aplikacji - w naszym przypadku jest serwer JBOSS w wersji 3.2.8 (rozpakowujemy plik jboss-3.2.8.SP1.tar.gz w katalogu domowym): Tworzymy katalog deploy w którym umieszczamy skompilowane pliki (katalog org). W katalogu deploy tworzymy katalog META-INF, w którym umieszczamy pliki MANIFEST-MF, ejb-jar.xml oraz jboss.xml. > tar -zxvf jboss-3.2.8.SP1.tar.gz Uruchamiamy serwer aplikacji: Tworzymy plik EJB-JAR: > ~/jboss-3.2.8.SP1/bin/run.sh > jar -cvf kalkulator.jar * Kompilujemy pliki komponentu EJB: Umieszczamy utworzony plik kalkulator.jar w podkatalogu server/default/deploy: > javac -classpath .:~/jboss-3.2.8.SP1/client/jboss-j2ee.jar -d . KalkulatorHome.java > javac -classpath .:~/jboss-3.2.8.SP1/client/jboss-j2ee.jar -d . KalkulatorBean.java > javac -classpath .:~/jboss-3.2.8.SP1/client/jboss-j2ee.jar -d . Kalkulator.java > cp kalkulator.jar ~/jboss-3.2.8.SP1/server/default/deploy} Wykład 9 – p. 21/24 Wykład 9 – p. Przykład (8/10) Przykład (9/10) Kod klienta: Kod klienta (cd.): package org.j2eesamples.kalkulator; import import import import import Object ref = jndiContext.lookup("kalkulator/Kalkulator"); KalkulatorHome home = (KalkulatorHome) PortableRemoteObject.narrow(ref, KalkulatorHome.class); System.out.println("Jest obiekt domowy!"); javax.naming.InitialContext; javax.rmi.PortableRemoteObject; org.j2eesamples.kalkulator.Kalkulator; org.j2eesamples.kalkulator.KalkulatorHome; java.util.Hashtable; Kalkulator kalkulator = home.create(); class KalkulatorKlient { public static void main(String[] args) { try { Hashtable<String,String> props = new Hashtable<String,String>(); props.put(InitialContext.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); props.put(InitialContext.PROVIDER_URL, "jnp://127.0.0.1:1099"); System.out.println(kalkulator.suma(2, 2)); } catch(Exception e) { System.out.println(e.toString()); } } } InitialContext jndiContext = new InitialContext(props); System.out.println("Jest kontekst!"); Wykład 9 – p. 23/24 Wykład 9 – p. Przykład (10/10) EJB 3.0 Kompilujemy kod klienta: > javac -classpath .:../../jboss-3.2.8.SP1/client/jboss-j2ee.jar -d . KalkulatorKlient.java Wraz z wersja˛ EJB 3.0 (Java EE) nastapiło ˛ znaczne uproszczenie technologii EJB: Na koniec możemy uruchomić klienta: mniejsza liczba plików źródłowych, dodatkowo sa˛ one „zwykłymi” interfejsami i klasami Java, > java -cp .:../../jboss-3.2.8.SP1/client/jbossall-client.jar org.j2eesamples.kalkulator.KalkulatorKlient deskryptory xml nie sa˛ obowiazkowe ˛ i zostały zastapione ˛ przez adnotacje, obiekty niezbedne ˛ do działania komponentu sa˛ „wstrzykiwane” mechanizmem dependency injection, zamiast wyszukiwania ich przez JNDI, komponenty encyjne zostały tak dalece uproszczone, że przestały być komponentami EJB i stanowia˛ odrebny ˛ standard o nazwie Java Persistance, oparty o odwzorowanie obiektowo-relacyjne. Wykład 9 – p. 25/24 Wykład 9 – p.