Wykład 9 - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
Wykład 9 - Instytut Informatyki Teoretycznej i Stosowanej
Oprogramowanie systemów równoległych i rozproszonych Wykład 9 Dr inż. Tomasz Olas [email protected] Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛estochowska Wykład 9 – p. 1/2 Platforma J2EE i EJB 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, wykorzystywane sa˛ do budowy złożonych aplikacji rozproszonych na zasadzie „składania z klocków”, obsługuje zdalnych i lokalnych klientów, klientami moga˛ być aplikacje serwlety, JSP, inne EJB. Wykład 9 – p. 2/2 Rola EJB na platformie J2EE 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. EJB realizuja˛ logik˛e biznesowa, ˛ zostawiajac ˛ innym elementom aplikacji logik˛e prezentacji. Wykład 9 – p. 3/2 Kiedy użyć EJB? Aplikacja musi być skalowalna możliwość rozproszenia komponentów Zaawansowane przetwarzanie transakcyjne kontener oferuje usługi transakcyjne deklaratywne specyfikowanie granic transakcji transakcje obiektowe Obsługa różnych typów klientów przegladarka ˛ klient aplikacyjny Wykład 9 – p. 4/2 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. Wykład 9 – p. 5/2 Rodzaje komponentów 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. 6/2 Komponenty sesyjne 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/2 Komponenty encyjne a sesyjne - różnice 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. 8/2 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. Wykład 9 – p. 9/2 Komponenty sterowane komunikatami 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. 10/2 Serwery aplikacji Przykładami serwerów Java EE sa: ˛ GlassFish (glassfish.dev.java.net), JBOSS (www.jboss.org), Sun Java Web Server (www.sun.com), BEA Weblogic (www.beasys.com), Borland Visibroker (www.borland.com), Caucho Resin (www.caucho.com), IBM WebSphere (www.ibm.com), Jakarta Tomcat (jakarta.apache.org), Oracle Application Server (www.oracle.com), Orion (www.orionserver.com), W3 Jigsaw (www.w3.org), itd. Wykład 9 – p. 11/2 Ogólny proces tworzenia komponentu EJB Przygotowanie kodu źródłowego klasy Java, reprezentujacej ˛ komponent EJB Utworzenie dwóch interfejsów Java, reprezentujacych ˛ punkty kontaktu świata zewnetrznego ˛ z komponentem EJB: interfejs Home, służacy ˛ do zarzadzania ˛ cyklem życia komponentu EJB interfejs Remote/Local, służacy ˛ do wywoływania metod logiki biznesowej komponentu EJB Przygotowanie XML-owego pliku konfiguracyjnego - deskryptora instalacji (Deployment Descriptor) Kompilacja całego przygotowanego kodu Java i utworzenie z niego pliku EJB JAR Umieszczenie przygotowanych plików w systemie plików serwera aplikacji; zarejestrowanie komponentu EJB Wykład 9 – p. 12/2 Komunikacja pomiedzy ˛ klientem a kontenerem Wykład 9 – p. 13/2 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. 14/2 Struktura archiwum EJB JAR Wykład 9 – p. 15/2 Przykład (1/10) 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. 16/2 Przykład (2/10) Interfejs domowy (KalkulatorHome): package org.j2eesamples.kalkulator; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface KalkulatorHome extends EJBHome { Kalkulator create() throws RemoteException, CreateException; } Wykład 9 – p. 17/2 Przykład (3/10) Klasa komponentu EJB (KalkulatorBean): package org.j2eesamples.kalkulator; 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 double suma(double x1, double x2) { return x1 + x2; } } Wykład 9 – p. 18/2 Przykład (4/10) Plik MANIFEST-MF: Manifest-Version: 1.0 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/2 Przykład (5/10) Plik ejb-jar.xml: <?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> Wykład 9 – p. 20/2 Przykład (6/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): > tar -zxvf jboss-3.2.8.SP1.tar.gz Uruchamiamy serwer aplikacji: > ~/jboss-3.2.8.SP1/bin/run.sh Kompilujemy pliki komponentu EJB: > 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 Wykład 9 – p. 21/2 Przykład (7/10) 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. Tworzymy plik EJB-JAR: > jar -cvf kalkulator.jar * Umieszczamy utworzony plik kalkulator.jar w podkatalogu server/default/deploy: > cp kalkulator.jar ~/jboss-3.2.8.SP1/server/default/deploy} Wykład 9 – p. 22/2 Przykład (8/10) Kod klienta: package org.j2eesamples.kalkulator; import import import import import javax.naming.InitialContext; javax.rmi.PortableRemoteObject; org.j2eesamples.kalkulator.Kalkulator; org.j2eesamples.kalkulator.KalkulatorHome; java.util.Hashtable; 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"); InitialContext jndiContext = new InitialContext(props); System.out.println("Jest kontekst!"); Wykład 9 – p. 23/2 Przykład (9/10) Kod klienta (cd.): Object ref = jndiContext.lookup("kalkulator/Kalkulator"); KalkulatorHome home = (KalkulatorHome) PortableRemoteObject.narrow(ref, KalkulatorHome.class); System.out.println("Jest obiekt domowy!"); Kalkulator kalkulator = home.create(); System.out.println(kalkulator.suma(2, 2)); } catch(Exception e) { System.out.println(e.toString()); } } } Wykład 9 – p. 24/2 Przykład (10/10) Kompilujemy kod klienta: > javac -classpath .:../../jboss-3.2.8.SP1/client/jboss-j2ee.jar -d . KalkulatorKlient.java Na koniec możemy uruchomić klienta: > java -cp .:../../jboss-3.2.8.SP1/client/jbossall-client.jar org.j2eesamples.kalkulator.KalkulatorKlient Wykład 9 – p. 25/2 EJB 3.0 Wraz z wersja˛ EJB 3.0 (Java EE) nastapiło ˛ znaczne uproszczenie technologii EJB: mniejsza liczba plików źródłowych, dodatkowo sa˛ one „zwykłymi” interfejsami i klasami Java, 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. 26/2