Wydawnictwo Helion
ul. Koœciuszki 1c
44-100 Gliwice
tel. 032 230 98 63
e-mail: helion@helion.pl
PRZYK£ADOWY ROZDZIA£
PRZYK£ADOWY ROZDZIA£
IDZ DO
IDZ DO
ZAMÓW DRUKOWANY KATALOG
ZAMÓW DRUKOWANY KATALOG
KATALOG KSI¥¯EK
KATALOG KSI¥¯EK
TWÓJ KOSZYK
TWÓJ KOSZYK
CENNIK I INFORMACJE
CENNIK I INFORMACJE
ZAMÓW INFORMACJE
O NOWOœCIACH
ZAMÓW INFORMACJE
O NOWOœCIACH
ZAMÓW CENNIK
ZAMÓW CENNIK
CZYTELNIA
CZYTELNIA
FRAGMENTY KSI¥¯EK ONLINE
FRAGMENTY KSI¥¯EK ONLINE
SPIS TREœCI
SPIS TREœCI
DODAJ DO KOSZYKA
DODAJ DO KOSZYKA
KATALOG ONLINE
KATALOG ONLINE
Enterprise JavaBeans
3.0. Wydanie V
Autorzy: Bill Burke, Richard Monson-Haefel
T³umaczenie: Miko³aj Szczepaniak, Krzysztof Ostrowski
ISBN: 83-246-0726-9
Tytu³ orygina³u:
Enterprise JavaBeans 3.0 (5th Edition)
Format: B5, stron: 760
Przyk³ady na ftp: 10150 kB
Wykorzystaj zaawansowane technologie tworzenia aplikacji korporacyjnych
• Poznaj architekturê EJB 3.0
• Stwórz w³asne komponenty
• Zaprojektuj w³asne us³ugi sieciowe na podstawie EJB 3.0
Enterprise JavaBeans to technologia przeznaczona do tworzenia z³o¿onych programów,
oparta na jêzyku Java i platformie Java Enterprise Edition. Stosowana jest przy
tworzeniu rozbudowanych aplikacji korporacyjnych i pozwala programistom na
generowanie mechanizmów automatycznego zarz¹dzania us³ugami kluczowymi dla
systemu. Wersje EJB stosowane do tej pory wymaga³y od twórców aplikacji
implementowania mechanizmów, które nie mia³y wiele wspólnego z w³aœciw¹ logik¹
biznesow¹ tworzonego oprogramowania, co znacznie wyd³u¿a³o i komplikowa³o proces
produkcji systemu. Najnowsza wersja, oznaczona numerem 3.0, jest pozbawiona tych wad.
Dziêki ksi¹¿ce „Enterprise JavaBeans 3.0. Wydanie V” poznasz najnowsze wcielenie
technologii EJB. Opisano tu wszystkie rozwi¹zania, które umo¿liwi³y uproszczenie
standardu Enterprise JavaBeans 3.0 wzglêdem jego poprzednich wersji. Czytaj¹c tê
ksi¹¿kê, poznasz nowy interfejs Java Persistence API, który zast¹pi³ stosowane
dotychczas komponenty encyjne zwyk³ymi obiektami Javy, oraz nauczysz siê
sposobów eliminowania koniecznoœci implementowania interfejsów EnterpriseBean.
Dowiesz siê, jak stosowaæ adnotacje w miejsce elementów jêzyka XML umieszczanych
w deskryptorach wdro¿enia. Znajdziesz tu równie¿ praktyczne przyk³ady, dziêki którym
b³yskawicznie opanujesz now¹ wersjê EJB.
• Architektura EJB 3.0
• Relacje pomiêdzy komponentami
• Zapytania i jêzyk EJB QL
• Komponenty sesyjne
• Obs³uga transakcji
• Implementowanie us³ug WWW
• Instalacja i konfiguracja serwera JBoss
Nie traæ wiêcej czasu! Zastosuj technologiê,
która u³atwi Ci wytwarzanie systemów korporacyjnych
5
Spis tre
ļci
S
ĥowo wstýpne ..............................................................................................................11
Przedmowa ................................................................................................................... 15
Cz
ýļë I Standard EJB 3.0
23
1. Wprowadzenie ..............................................................................................................25
Komponenty serwerowe
26
Utrwalanie danych i komponenty encyjne
28
Asynchroniczne przesyäanie komunikatów
29
Usäugi Web Services
31
Titan Cruises — wymyĈlone przedsiöbiorstwo
33
Co dalej?
33
2. Przegl
éd architektury ...................................................................................................35
Komponent encyjny
35
Komponent biznesowy (korporacyjny)
39
Stosowanie komponentów EJB i komponentów encyjnych
48
Kontrakt komponent-kontener
54
Podsumowanie
55
3. Zarz
édzanie zasobami i usĥugi podstawowe ..............................................................57
Zarzñdzanie zasobami
57
Usäugi podstawowe
66
Co dalej?
78
4. Konstruowanie pierwszych komponentów ................................................................79
Wytwarzanie komponentu encyjnego
79
Wytwarzanie komponentu sesyjnego
82
6
_
Spis tre
ļci
5. Utrwalanie: us
ĥuga EntityManager ............................................................................. 91
Encje sñ obiektami POJO
92
Encje zarzñdzane kontra encje niezarzñdzane
93
Pakowanie jednostek utrwalania
96
Uzyskiwanie dostöpu do usäugi EntityManager
100
Techniki wspóäpracy z usäugñ EntityManager
104
Transakcje zasobów lokalnych
111
6. Odwzorowywanie obiektów trwa
ĥych ......................................................................115
Model programowania
116
Podstawy odwzorowaþ relacyjnych
119
Klucze gäówne
123
Odwzorowywanie wäaĈciwoĈci
133
Odwzorowania w wielu tabelach i adnotacja @SecondaryTable
140
Obiekty osadzone (oznaczone adnotacjñ @Embedded)
143
7. Relacje
ĥéczéce komponenty encyjne ........................................................................145
Siedem rodzajów relacji
145
Odwzorowywanie relacji reprezentowanych przez kolekcje
178
Encje odäñczone i typ wyliczeniowy FetchType
181
Propagacja kaskadowa
182
8. Dziedziczenie encji ..................................................................................................... 187
Reprezentacja hierarchii klas w formie pojedynczej tabeli
188
Jedna tabela dla konkretnej klasy
191
Jedna tabela dla kaĔdej podklasy
193
Strategie mieszane
195
Nieencyjne klasy bazowe
196
9. Zapytania i j
ýzyk EJB QL .............................................................................................199
Interfejs Query API
200
Jözyk EJB QL
204
Zapytania rdzenne
231
Zapytania nazwane
235
10. Wywo
ĥania zwrotne i klasy nasĥuchujéce .................................................................239
Zdarzenia zwrotne
239
Wywoäania zwrotne klas komponentów encyjnych
240
Klasy nasäuchujñce encji
241
Spis tre
ļci
_
7
11. Komponenty sesyjne .................................................................................................. 245
Bezstanowy komponent sesyjny
247
Interfejs SessionContext
258
Cykl Ĕycia bezstanowego komponentu sesyjnego
261
Stanowy komponent sesyjny
265
Cykl Ĕycia stanowego komponentu sesyjnego
276
Stanowe komponenty sesyjne i rozszerzone konteksty utrwalania
280
ZagnieĔdĔanie stanowych komponentów sesyjnych
281
12. Komponenty sterowane komunikatami ................................................................... 283
Usäuga JMS i komponenty sterowane komunikatami
283
Komponenty sterowane komunikatami JMS
295
Cykl Ĕycia komponentu sterowanego komunikatami
309
Komponenty sterowane komunikatami wykorzystujñce konektory
311
Wiñzanie komunikatów
314
13. Us
ĥuga Timer Service .................................................................................................. 319
Harmonogram konserwacji statków linii Titan
321
Interfejs Timer Service API
321
Transakcje
331
Liczniki czasowe bezstanowych komponentów sesyjnych
331
Liczniki czasowe komponentów sterowanych komunikatami
334
Säowo koþcowe
340
14. Kontekst JNDI ENC i mechanizm wstrzykiwania ...................................................... 341
Kontekst JNDI ENC
341
Referencje i rodzaje wstrzykniöè
349
15. Obiekty przechwytuj
éce .............................................................................................377
Metody przechwytujñce
377
Obiekty przechwytujñce i wstrzykiwanie
385
Przechwytywanie zdarzeþ zwiñzanych z cyklem Ĕycia komponentu
387
Obsäuga wyjñtków
390
Cykl Ĕycia obiektu przechwytujñcego
393
Stosowanie adnotacji @AroundInvoke dla metod samych komponentów EJB
394
Kierunki rozwoju obiektów przechwytujñcych
394
16. Transakcje ....................................................................................................................397
Transakcje ACID
397
Deklaracyjne zarzñdzanie transakcjami
402
Izolacja i zabezpieczanie bazy danych
412
8
_
Spis tre
ļci
Nietransakcyjne komponenty EJB
422
Jawne zarzñdzanie transakcjami
423
Wyjñtki i transakcje
433
Transakcyjne stanowe komponenty sesyjne
438
Konwersacyjny kontekst trwaäoĈci
440
17. Bezpiecze
ħstwo ..........................................................................................................447
Uwierzytelnianie i toĔsamoĈè
448
Autoryzacja
449
Identyfikator bezpieczeþstwa RunAs
454
Bezpieczeþstwo programowe
456
18. EJB 3.0: standardy us
ĥug WWW ................................................................................ 459
Ogólnie o usäugach WWW
459
XML Schema oraz XML Namespaces
460
SOAP 1.1
470
WSDL 1.1
473
UDDI 2.0
480
Od standardu do implementacji
480
19. EJB 3.0 i us
ĥugi WWW .................................................................................................481
Dostöp do usäug WWW za pomocñ JAX-RPC
482
Definiowanie usäugi WWW za pomocñ JAX-RPC
490
Korzystanie z JAX-WS
494
Inne adnotacje i API
503
20. Java EE .........................................................................................................................505
Serwlety
505
Strony JavaServer
507
Komponenty WWW i EJB
507
Wypeänianie luki
508
Skäadanie kawaäków w jednñ caäoĈè
513
21. Projektowanie EJB w zastosowaniach rzeczywistych ............................................. 515
Projekt wstöpny — kontenery i bazy danych
515
Projekt wäaĈciwy
517
Czy korzystaè z EJB?
540
Opakowywanie
545
Spis tre
ļci
_
9
Cz
ýļë II Podrýcznik użytkownika serwera JBoss
547
Wprowadzenie ..................................................................................................................... 549
22. Instalacja i konfiguracja serwera JBoss ..................................................................... 551
O serwerze JBoss
551
Instalacja serwera aplikacji JBoss
552
Krótki przeglñd struktury wewnötrznej serwera JBoss
555
WdraĔanie i konfigurowanie kodu Ēródäowego èwiczeþ
558
23.
êwiczenia do rozdziaĥu 4. .......................................................................................... 561
çwiczenie 4.1. Pierwsze komponenty w serwerze JBoss
561
çwiczenie 4.2. Deklarowanie zwiñzków z interfejsem JNDI za pomocñ adnotacji
571
çwiczenie 4.3. Deklarowanie zwiñzków z interfejsem JNDI
za pomocñ elementów jözyka XML
573
24.
êwiczenia do rozdziaĥu 5. ..........................................................................................577
çwiczenie 5.1. Interakcja z usäugñ EntityManager
577
çwiczenie 5.2. Utrwalanie w autonomicznych aplikacjach Javy
587
25.
êwiczenia do rozdziaĥu 6. .......................................................................................... 591
çwiczenie 6.1. Podstawowe odwzorowywanie wäaĈciwoĈci
591
çwiczenie 6.2. Adnotacja @IdClass
595
çwiczenie 6.3. Adnotacja @EmbeddedId
597
çwiczenie 6.4. Odwzorowywanie pojedynczych encji w wielu tabelach
599
çwiczenie 6.5. Klasy osadzone
601
26.
êwiczenia do rozdziaĥu 7. ...........................................................................................605
çwiczenie 7.1. Propagacja kaskadowa
605
çwiczenie 7.2. Relacje odwrotne
611
çwiczenie 7.3. Leniwa inicjalizacja
615
27.
êwiczenia do rozdziaĥu 8. .......................................................................................... 621
çwiczenie 8.1. Strategia odwzorowywania hierarchii w pojedynczych tabelach
621
çwiczenie 8.2. Strategia odwzorowywania klas w pojedynczych tabelach
625
çwiczenie 8.3. Strategia dziedziczenia JOINED
627
28.
êwiczenia do rozdziaĥu 9. .......................................................................................... 631
çwiczenie 9.1. Interfejs Query i podstawy jözyka zapytaþ EJB QL
631
çwiczenie 9.2. Rdzenne zapytania jözyka SQL
649
10
_
Spis tre
ļci
29.
êwiczenia do rozdziaĥu 10. .........................................................................................655
çwiczenie 10.1. Wywoäania zwrotne
655
çwiczenie 10.2. Obiekty nasäuchujñce
660
30.
êwiczenia do rozdziaĥu 11. .........................................................................................667
çwiczenie 11.1. Wywoäania zwrotne
667
çwiczenie 11.2. Przykrywanie ustawieþ za pomocñ elementów XML-a
671
çwiczenie 11.3. Bezstanowy komponent sesyjny bez adnotacji
674
çwiczenie 11.4. Stanowy komponent sesyjny
676
çwiczenie 11.5. Stanowy komponent sesyjny bez adnotacji
682
31.
êwiczenia do rozdziaĥu 12. ........................................................................................ 685
çwiczenie 12.1. Komponent sterowany komunikatami
685
32.
êwiczenia do rozdziaĥu 13. .........................................................................................693
çwiczenie 13.1. Usäuga EJB Timer Service
693
33.
êwiczenia do rozdziaĥu 15. .........................................................................................697
çwiczenie 15.1. Obiekty przechwytujñce EJB
697
çwiczenie 15.2. Przechwytywanie wywoäaþ zwrotnych EJB
699
34.
êwiczenia do rozdziaĥu 16. .........................................................................................703
çwiczenie 16.1. Konwersacyjny kontekst trwaäoĈci
703
35.
êwiczenia do rozdziaĥu 17. .........................................................................................707
çwiczenie 17.1. Bezpieczeþstwo
707
çwiczenie 17.2. Zabezpieczanie za pomocñ XML
712
36.
êwiczenia do rozdziaĥu 19. .............................................................................................. 715
çwiczenie 19.1. Udostöpnianie komponentu bezstanowego
715
çwiczenie 19.2. Korzystanie z klienta .NET
722
Dodatki
725
A Konfiguracja bazy danych JBoss ................................................................................ 727
Skorowidz .................................................................................................................... 731
57
ROZDZIA
Ĥ 3.
Zarz
édzanie zasobami
i us
ĥugi podstawowe
W rozdziale 2. opisano podstawy architektury technologii Enterprise JavaBeans i Java Persi-
stence, w tym relacje äñczñce klasö komponentu, kontener EJB oraz usäugö
EntityManager
.
Relacje pomiödzy wymienionymi elementami interesujñcej nas architektury skäadajñ siö od-
powiednio na wspólny model rozproszonych komponentów serwera oraz na model utrwala-
nia, który moĔe byè stosowany zarówno w aplikacjach dziaäajñcych po stronie serwera, jak
i w aplikacjach autonomicznych. Same modele w tej formie nie wystarczñ do tego, by tech-
nologia Enterprise JavaBeans zainteresowaäa programistów i staäa siö bardziej funkcjonalna
od innych popularnych architektur. Serwery EJB dodatkowo muszñ zarzñdzaè zasobami wy-
korzystywanymi przez komponenty i z reguäy oferujñ moĔliwoĈè jednoczesnego zarzñdzania
tysiñcami lub wröcz milionami obiektów rozproszonych. WäaĈnie do serwera EJB naleĔy za-
rzñdzanie sposobem wykorzystywania przez obiekty rozproszone pamiöci, wñtków, poäñczeþ
z bazñ danych, mocy obliczeniowej itp. Co wiöcej, specyfikacja EJB definiuje interfejsy, które
uäatwiajñ programistom korzystanie z wymienionych mechanizmów.
Serwery EJB oferujñ piöè podstawowych usäug: wspóäbieĔnoĈè, zarzñdzanie transakcjami,
utrwalanie danych, rozpraszanie obiektów, nazewnictwo oraz bezpieczeþstwo. Wymienione
usäugi stanowiñ rodzaj infrastruktury niezbödnej do wäaĈciwej pracy systemu trójwarstwo-
wego. Specyfikacja Enterprise JavaBeans opisuje teĔ dwie usäugi dodatkowe: asynchroniczne
przesyäanie komunikatów i licznik czasowy.
W niniejszym rozdziale skoncentrujemy siö na elementach funkcjonalnoĈci odpowiedzialnych
za zarzñdzanie zasobami oraz na najwaĔniejszych usäugach (tzw. usäugach podstawowych)
oferowanych komponentom Enterprise JavaBeans przez ich serwery.
Zarz
édzanie zasobami
Wielkie systemy biznesowe charakteryzujñce duĔñ liczbñ uĔytkowników mogñ wymagaè
jednoczesnego istnienia i realizacji wäaĈciwych zadaþ przez tysiñce lub wröcz miliony obiektów.
Wraz ze wzrostem liczby wspólnych operacji podejmowanych przez te obiekty dziaäania w takich
obszarach jak zarzñdzanie wspóäbieĔnoĈciñ czy przetwarzanie transakcyjne mogñ prowadziè
do wydäuĔenia czasu odpowiedzi i — tym samym — frustracji uĔytkowników. Serwery En-
terprise JavaBeans próbujñ optymalizowaè pracö systemów EJB, synchronizujñc wspólne
dziaäania rozproszonych obiektów i wymuszajñc wspóädzielenie najcenniejszych zasobów.
58
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Jest pewna zaleĔnoĈè pomiödzy liczbñ klientów a liczbñ obiektów rozproszonych, których ist-
nienie jest warunkiem koniecznym sprawnej obsäugi tych klientów. Obsäuga wiökszej liczby
klientów z oczywistych wzglödów wymaga wiökszej liczby obiektów rozproszonych. Istnieje
punkt, od którego wzrost liczby klientów powoduje spadek wydajnoĈci i przepustowoĈci caäego
systemu. Specyfikacja Enterprise JavaBeans opisuje dwa mechanizmy, których zadaniem jest
uäatwienie zarzñdzania duĔñ liczbñ komponentów w czasie wykonywania: mechanizm za-
rzñdzania pulñ egzemplarzy oraz mechanizm aktywacji. Twórcy technologii EJB dodatkowo
zdecydowali siö uĔyè do zarzñdzania poäñczeniami z zasobami architektury Java EE Con-
nector Architecture (czyli konektory Java EE Connectors). Wraz ze wzrostem liczby obiektów
rozproszonych i klientów z natury rzeczy musi rosnñè takĔe liczba poäñczeþ z zasobami.
Konektory Java EE Connectors mogñ byè wykorzystywane przez kontener EJB do zarzñdzania
poäñczeniami z bazami danych, systemami przesyäania komunikatów, systemami ERP, ist-
niejñcymi systemami informatycznymi oraz pozostaäymi typami zasobów.
Zarz
édzanie pulé egzemplarzy
Koncepcja tworzenia puli zasobów nie jest Ĕadnñ nowoĈciñ. Przykäadowo wiökszoĈè baz da-
nych tworzy i zarzñdza pulñ poäñczeþ, która umoĔliwia obiektom biznesowym wchodzñcym
w skäad danego systemu wspóädzielenie dostöpu do zasobów bazy danych. W ten sposób
moĔna stosunkowo äatwo ograniczyè liczbö potrzebnych poäñczeþ, co z kolei pozwala zmniej-
szyè poziom wykorzystania zasobów i — tym samym — przekäada siö na wyĔszñ przepu-
stowoĈè. Architekturö Java EE Connector Architecture (JCA), która jest czösto wykorzystywana
przez kontenery EJB wäaĈnie do zarzñdzania pulñ poäñczeþ z bazami danych i innymi zaso-
bami, szczegóäowo omówimy w dalszej czöĈci tego rozdziaäu. WiökszoĈè kontenerów EJB sto-
suje mechanizmy zarzñdzania pulñ zasobów dla komponentów serwera — ta technika czösto
jest okreĈlana mianem zarzñdzania pulñ egzemplarzy (ang. instance pooling). Pula egzemplarzy
ogranicza liczbö egzemplarzy komponentów (a wiöc takĔe zasobów) niezbödnych do obsäugi
Ĕñdaþ generowanych przez oprogramowanie klienckie.
Jak wiemy, aplikacje klienckie wspóäpracujñ z komponentami sesyjnymi za poĈrednictwem
interfejsów zdalnych i lokalnych implementowanych przez odpowiednie obiekty EJB. Ozna-
cza to, Ĕe oprogramowanie klienckie nigdy nie ma bezpoĈredniego dostöpu do wäaĈciwych
egzemplarzy klas komponentów sesyjnych. Podobnie aplikacje klienckie systemu JMS nigdy
nie wspóäpracujñ bezpoĈrednio z komponentami sterowanymi komunikatami JMS (kompo-
nentami JMS-MDB). Komunikaty wysyäane przez te aplikacje sñ kierowane do systemu kon-
tenera EJB, który odpowiada za ich dostarczanie do odpowiednich egzemplarzy komponentów
sterowanych komunikatami.
Zarzñdzanie pulñ egzemplarzy jest moĔliwe, poniewaĔ aplikacje klienckie nigdy nie uzyskujñ
bezpoĈredniego dostöpu do komponentów. W zwiñzku z tym utrzymywanie odröbnej kopii
kaĔdego z komponentów EJB dla kaĔdego klienta nie jest konieczne. Serwer EJB moĔe z po-
wodzeniem realizowaè te same zadania, utrzymujñc mniejszñ liczbö egzemplarzy kompo-
nentów EJB, poniewaĔ pojedyncze egzemplarze tych komponentów mogñ by
è wielokrotnie
wykorzystywane do obsäugi róĔnych Ĕñdaþ. Mimo Ĕe opisywane podejĈcie wielu programistom
moĔe siö wydawaè niebezpieczne, dobrze zaprojektowany i zaimplementowany mechanizm
zarzñdzania pulñ egzemplarzy moĔe znacznie ograniczyè iloĈè zasobów potrzebnych do ob-
säugi wszystkich Ĕñdaþ generowanych przez oprogramowanie klienckie.
Zarz
édzanie zasobami
_
59
Cykl
życia bezstanowego komponentu sesyjnego
Aby jak najlepiej zrozumieè sposób dziaäania puli egzemplarzy, warto przeanalizowaè cykl
Ĕycia bezstanowego komponentu sesyjnego. Ogólnie bezstanowy komponent sesyjny moĔe siö
znajdowaè w trzech stanach:
Brak stanu
W tym stanie znajdujñ siö te egzemplarze komponentów, które nie zostaäy jeszcze zaini-
cjalizowane. Warto identyfikowaè ten specyficzny stan, poniewaĔ dobrze reprezentuje
sytuacjö z poczñtku i koþca cyklu Ĕycia egzemplarza komponentu.
W puli
Kiedy egzemplarz komponentu znajduje siö w tym stanie, wiemy, Ĕe zostaä zainicjalizowany
przez kontener, ale jeszcze nie zwiñzano go z Ĕadnym Ĕñdaniem wygenerowanym przez
oprogramowanie klienckie.
Stan gotowo
Ĉci
Egzemplarz komponentu EJB znajdujñcy siö w tym stanie zostaä zwiñzany z konkretnym
Ĕñdaniem EJB i jest gotowy do przetworzenia przychodzñcych wywoäaþ metod biznesowych.
PoniewaĔ bezstanowe komponenty sesyjne nie utrzymujñ swojego stanu pomiödzy kolejnymi
wywoäaniami metod, kaĔde z tych wywoäaþ jest niezaleĔne od pozostaäych — moĔe wykony-
waè swoje zadania bez koniecznoĈci odwoäywania siö do zmiennych egzemplarzy. Oznacza to,
Ĕe dowolny egzemplarz bezstanowego komponentu sesyjnego moĔe obsäugiwaè Ĕñdania dowolnego
obiektu EJB pod warunkiem, Ĕe rodzaj i format tych Ĕñdaþ jest wäaĈciwy. Kontener EJB moĔe wiöc
wymieniaè egzemplarze komponentu sesyjnego nawet pomiödzy kolejnymi wywoäaniami metod.
KaĔdy producent kontenera EJB implementuje mechanizm zarzñdzania pulñ egzemplarzy
w nieco inny sposób, jednak wszystkie strategie tworzenia tego rodzaju pul majñ na celu takie
zarzñdzanie kolekcjami egzemplarzy komponentów, które w czasie wykonywania zagwa-
rantuje moĔliwie szybki dostöp do tych egzemplarzy. Podczas konstruowania puli egzempla-
rzy kontener EJB tworzy wiele egzemplarzy klasy pojedynczego komponentu i utrzymuje je
w wewnötrznej kolekcji do chwili, w której okaĔñ siö potrzebne. W odpowiedzi na Ĕñdania
metod biznesowych generowanych przez aplikacje klienckie kontener EJB przypisuje poszcze-
gólnym klientom egzemplarze komponentu wchodzñce w skäad dostöpnej puli. Po zakoþ-
czeniu przetwarzania Ĕñdania, kiedy odpowiedni obiekt EJB nie jest juĔ potrzebny, nastöpuje
jego zwrócenie do puli egzemplarzy. Serwer EJB utrzymuje pule egzemplarzy dla kaĔdego
wdroĔonego typu bezstanowego komponentu sesyjnego. Warto pamiötaè, Ĕe kaĔdy egzem-
plarz wchodzñcy w skäad puli egzemplarzy jest elementem równoprawnym — wszystkie eg-
zemplarze sñ traktowane w identyczny sposób. Egzemplarze sñ wybierane z puli i przydzielane
kolejnym Ĕñdaniom EJB w sposób caäkowicie przypadkowy (Ĕaden z egzemplarzy nie ma
pozycji uprzywilejowanej wzglödem pozostaäych).
Na rysunku 3.1 przedstawiono schemat wymiany egzemplarzy pomiödzy kolejnymi wywo-
äaniami metod bezstanowego komponentu sesyjnego. Na rysunku 3.1a widaè egzemplarz A
obsäugujñcy wywoäanie metody biznesowej przekazane przez 1. obiekt EJB. Po zakoþczeniu
obsäugi tego Ĕñdania egzemplarz A wraca do puli egzemplarzy (patrz rysunek 3.1b). Kiedy
do systemu EJB dociera wywoäanie metody 2. obiektu EJB, egzemplarz A jest wiñzany z tym
obiektem na czas trwania bieĔñcej operacji (patrz rysunek 3.1c). W czasie, gdy egzemplarz A
obsäuguje Ĕñdanie 2. obiektu EJB, 1. obiekt EJB otrzymuje wygenerowane przez oprogramo-
wanie klienckie wywoäanie innej metody — nowe Ĕñdanie jest obsäugiwane przez egzem-
plarz B (patrz rysunek 3.1d).
60
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Rysunek 3.1. Strategia wymiany egzemplarzy bezstanowych komponentów sesyjnych
Opisana strategia wymiany egzemplarzy bezstanowych komponentów sesyjnych umoĔliwia
efektywnñ obsäugö kilkuset aplikacji klienckich za pomocñ zaledwie kilku egzemplarzy bez-
stanowego komponentu sesyjnego, poniewaĔ czas potrzebny do wykonania wiökszoĈci wy-
woäaþ metod z reguäy jest znacznie krótszy od przerw dzielñcych kolejne wywoäania. Egzem-
plarz komponentu, który koþczy obsäugö Ĕñdania wygenerowanego przez obiekt EJB, natychmiast
jest dostöpny dla dowolnego innego obiektu EJB, który tego potrzebuje. Takie rozwiñzanie
umoĔliwia znacznie mniejszej liczbie bezstanowych komponentów sesyjnych obsäugö wiök-
szej liczby Ĕñdaþ, co automatycznie przekäada siö na mniejsze wykorzystanie zasobów i wyĔszñ
wydajnoĈè.
JeĈli dany komponent sesyjny Ĕñda wstrzykniöcia egzemplarza interfejsu
javax.ejb.EJBContext
,
zaraz po umieszczeniu jego egzemplarza w odpowiedniej puli nastöpuje przekazanie referen-
cji do wäaĈciwego obiektu kontekstu (wiöcej informacji na ten temat moĔna znaleĒè w rozdziale
14.). Interfejs
EJBContext
moĔe byè wykorzystywany przez komponenty do komunikowania
siö z ich Ĉrodowiskiem EJB. Interfejs
EJBContext
jest szczególnie przydatny w czasie, gdy dany
egzemplarz komponentu znajduje siö w stanie gotowoĈci.
W czasie obsäugi Ĕñdania przez egzemplarz komponentu interfejs
EJBContext
nabiera nieco
innego znaczenia, poniewaĔ oferuje informacje o aplikacji klienckiej korzystajñcej z danego
komponentu. Co wiöcej, interfejs
EJBContext
zapewnia egzemplarzowi komponentu dostöp
Zarz
édzanie zasobami
_
61
do jego namiastki poĈrednika EJB, co nie jest bez znaczenia w sytuacji, gdy dany komponent
musi przekazywaè referencje do samego siebie i (lub) pozostaäych komponentów EJB. Ozna-
cza to, Ĕe interfejs
EJBContext
w Ĕadnym razie nie jest strukturñ statycznñ — jest dynamicznym
interfejsem kontenera EJB.
Bezstanowe komponenty sesyjne deklarujemy jako „bezstanowe”, stosujñc adnotacjö
@javax.
ejb.Stateless
w kodzie Ēródäowym lub odpowiednie zapisy w deskryptorze wdroĔenia.
Od momentu wdroĔenia klasy naszego bezstanowego komponentu sesyjnego kontener zakäada,
Ĕe pomiödzy kolejnymi wywoäaniami metod nie jest utrzymywany stan konwersacji. Bezstanowe
komponenty sesyjne mogñ zawieraè zmienne egzemplarzy, jednak z uwagi na moĔliwoĈè ob-
säugi wielu róĔnych obiektów EJB przez pojedynczy egzemplarz takiego komponentu tego
rodzaju zmienne nie powinny byè wykorzystywane do reprezentowania stanu konwersacji.
Komponenty sterowane komunikatami i pula egzemplarzy
Podobnie jak bezstanowe komponenty sesyjne, komponenty sterowane komunikatami nie
utrzymujñ stanów wäaĈciwych dla poszczególnych Ĕñdaþ i jako takie doskonale nadajñ siö do
skäadowania w puli egzemplarzy.
W wiökszoĈci kontenerów EJB dla kaĔdego typu komponentów sterowanych komunikatami
jest tworzona osobna pula egzemplarzy odpowiedzialnych za obsäugö komunikatów przycho-
dzñcych. Komponenty JMS-MDB rejestrujñ swoje zainteresowanie okreĈlonymi rodzajami
komunikatów (kierowanych w okreĈlone miejsce, rodzaj adresu wykorzystywanego podczas
wysyäania i odbierania komunikatów). Kiedy asynchroniczny komunikat jest wysyäany przez
klienta systemu JMS, komunikat trafia do kontenera EJB zawierajñcego komponenty, które
zarejestrowaäy siö jako odbiorcy tego rodzaju komunikatów. Kontener EJB odpowiada za
okreĈlenie, który komponent JMS-MDB powinien otrzymaè nowy komunikat, po czym wy-
biera z puli jeden egzemplarz tego komponentu, któremu zostanie zlecona obsäuga danego
komunikatu. Kiedy wybrany egzemplarz komponentu JMS-MDB zakoþczy przetwarzanie tego
komunikatu (gdy wywoäana metoda
onMessage()
zwróci sterowanie), kontener EJB zwróci
ten egzemplarz do odpowiedniej puli. Sposób przetwarzania Ĕñdaþ aplikacji klienckich przez
kontener EJB przedstawiono na rysunku 3.2.
Rysunek 3.2. Pula egzemplarzy komponentów JMS-MDB
62
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Na rysunku 3.2a przedstawiono sytuacjö, w której pierwszy klient JMS dostarcza komunikat
kierowany pod adres A, natomiast ostatni (trzeci) klient JMS dostarcza komunikat kierowany
pod adres B. Kontener EJB wybiera egzemplarz komponentu
MessageDrivenBean_1
, który
ma przetworzyè komunikat kierowany pod adres A, oraz egzemplarz komponentu
Message-
DrivenBean_2
, który ma przetworzyè komunikat kierowany pod adres B. Egzemplarze obu
wymienionych komponentów sñ na czas przetwarzania odpowiednich komunikatów usu-
wane z puli.
Na rysunku 3.2b przedstawiono sytuacjö, która ma miejsce chwilö póĒniej — Ĉrodkowy (drugi)
klient JMS wysyäa komunikat kierowany pod adres B. Na tym etapie pierwsze dwa komuni-
katy zostaäy juĔ przetworzone, zatem naleĔy przyjñè, Ĕe kontener EJB zwróciä oba egzemplarze
komponentów sterowanych komunikatami do wäaĈciwych pul. W reakcji na otrzymanie
nowego komunikatu kontener wybiera nowy egzemplarz komponentu
MessageDrivenBean_2
,
którego zadaniem bödzie przetworzenie tego komunikatu.
Komponenty JMS-MDB zawsze sñ wdraĔane z myĈlñ o przetwarzaniu komunikatów kiero-
wanych w okreĈlone miejsce docelowe. Przykäadowo na rysunku 3.2 egzemplarze komponentu
MessageDrivenBean_1
przetwarzajñ tylko komunikaty kierowane pod adres A, natomiast eg-
zemplarze komponentu
MessageDrivenBean_2
przetwarzajñ wyäñcznie komunikaty z adresem
docelowym B. Warto pamiötaè, Ĕe istnieje moĔliwoĈè jednoczesnego przetwarzania wielu
komunikatów kierowanych pod ten sam adres. Przykäadowo jeĈli system EJB nagle otrzyma
sto komunikatów kierowanych z adresem docelowym A, kontener EJB bödzie musiaä wybraè
z puli sto egzemplarzy komponentu
MessageDrivenBean_1
, które przetworzñ te komunikaty
przychodzñce (kaĔdemu egzemplarzowi zostanie przydzielony inny komunikat).
W specyfikacji Enterprise JavaBeans 2.1 i kolejnych wersjach rozszerzono rolö komponentów
sterowanych komunikatami, rezygnujñc z ograniczania ich moĔliwoĈci do jednego systemu
przesyäania komunikatów — obecnie komponenty MDB oprócz systemu JMS mogñ wspóä-
pracowaè takĔe z innymi usäugami i interfejsami API przesyäania komunikatów. Ten odwaĔ-
ny krok otworzyä komponenty sterowane komunikatami na niemal dowolne rodzaje zaso-
bów, wäñcznie z systemami przesyäania komunikatów alternatywnymi wzglödem systemu
JMS, takimi systemami ERP jak SAP oraz istniejñcymi systemami informatycznymi (np. IMS).
NiezaleĔnie od rodzaju zasobów reprezentowanych przez dany komponent sterowany komu-
nikatami, jego egzemplarze sñ skäadowane w puli w dokäadnie taki sam sposób jak egzem-
plarze komponentów JMS-MDB.
Mechanizm aktywacji
W przeciwieþstwie do pozostaäych rodzajów komponentów EJB stanowe komponenty sesyjne
utrzymujñ swój stan pomiödzy kolejnymi wywoäaniami metod. Tzw. stan konwersacji (ang.
conversational state) reprezentuje konwersacjö z klientem stanowego komponentu sesyjnego.
IntegralnoĈè takiego stanu konwersacji wymaga jego utrzymywania przez caäy czas trwania
obsäugi Ĕñdaþ klienta przez dany komponent. Inaczej niĔ w przypadku bezstanowych kom-
ponentów sesyjnych i komponentów sterowanych komunikatami egzemplarze stanowych
komponentów sesyjnych nie sñ skäadowane w ramach puli. Zamiast tego stanowe kompo-
nenty sesyjne wykorzystujñ mechanizm aktywacji, który takĔe pozwala na pewne oszczödno-
Ĉci w zakresie wykorzystywanych zasobów. Kiedy serwer EJB musi zachowaè jakieĈ zasoby,
moĔe po prostu usunñè stanowe komponenty sesyjne z pamiöci. Stan konwersacji usuniötego
komponentu jest serializowany w pamiöci pomocniczej. Kiedy klient wywoäuje metodö
Zarz
édzanie zasobami
_
63
obiektu EJB, kontener EJB tworzy egzemplarz stanowego komponentu sesyjnego i odtwarza
w nowym egzemplarzu stan zachowany w chwili usuwania z pamiöci jego poprzednika.
Pasywacja (ang. passivation) polega na rozäñczeniu stanowego komponentu sesyjnego od
obiektu EJB oraz na zachowaniu jego stanu w pamiöci pomocniczej. Pasywacja wymaga skäa-
dowania stanu konwersacji pomiödzy egzemplarzem komponentu a odpowiednim obiektem
EJB. Po wykonaniu pasywacji egzemplarz komponentu jest bezpiecznie usuwany zarówno
z obiektu EJB, jak i z pamiöci. Aplikacje klienckie w ogóle nie sñ informowane o procesach
pasywacji. Warto pamiötaè, Ĕe oprogramowanie klienckie wykorzystuje zdalnñ referencjö do
komponentu implementowanñ przez namiastkö poĈrednika EJB, zatem klient moĔe byè poäñ-
czony z obiektem EJB takĔe po przeprowadzeniu pasywacji.
Aktywacja (ang. activation) polega na przywróceniu stanu konwersacji egzemplarza stano-
wego komponentu sesyjnego z obiektem EJB. W momencie wywoäania metody obiektu EJB,
który byä przedmiotem pasywacji, kontener automatycznie tworzy nowy egzemplarz odpo-
wiedniego komponentu i przypisuje jego polom dane zapisane w czasie pasywacji. Obiekt
EJB moĔe nastöpnie delegowaè wspomniane wywoäanie metody do nowo utworzonego eg-
zemplarza komponentu sesyjnego. Procesy aktywacji i pasywacji stanowego komponentu se-
syjnego przedstawiono na rysunku 3.3. Rysunek 3.3a ilustruje sytuacjö, w której komponent
podlega pasywacji. Stan konwersacji egzemplarza B z obsäugiwanym obiektem EJB jest od-
czytywany i utrwalany. Na rysunku 3.3b przedstawiono moment pasywacji i zapisywania stanu.
Od tej pory dany obiekt EJB nie jest juĔ zwiñzany ze wspomnianym egzemplarzem kompo-
nentu. Aktywacjö tego komponentu przedstawiono na rysunku 3.3c. Rysunek ten prezentuje
sytuacjö, w której nowy egzemplarz, nazwany C, jest tworzony, wypeäniany danymi repre-
zentujñcymi stan zapisany w czasie pasywacji i ostatecznie wiñzany z tym samym obiektem EJB,
z którym przed pasywacjñ wspóäpracowaä egzemplarz B.
Rysunek 3.3. Procesy pasywacji i aktywacji
64
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
PoniewaĔ sama klasa stanowego komponentu sesyjnego nie musi oferowaè moĔliwoĈci se-
rializacji, konkretne rozwiñzania stosowane w mechanizmach aktywacji i pasywacji tego ro-
dzaju komponentów zaleĔñ od producenta kontenera EJB. Warto pamiötaè, Ĕe np. wäaĈciwo-
Ĉci
transient
mogñ nie byè traktowane przez mechanizmy odpowiedzialne za aktywacjö
i pasywacjö dokäadnie tak, jak tego oczekujemy. Przykäadowo w czasie deserializacji obiektu
Javy jego polom przejĈciowym zawsze sñ przypisywane wartoĈci poczñtkowe wäaĈciwe dla
ich typów. Pola typu
Integer
majñ przypisywanñ wartoĈè
0
, pola typu
Boolean
majñ przypi-
sywanñ wartoĈè
false
, referencje do obiektów majñ przypisywanñ wartoĈè
null
itd. W sys-
temach EJB pola przejĈciowe aktywowanych komponentów nie majñ przywracanych warto-
Ĉci poczñtkowych, tylko albo zachowujñ swoje wartoĈci oryginalne, albo wartoĈci dowolne.
Stosujñc pola przejĈciowe, naleĔy zachowywaè szczególnñ ostroĔnoĈè, poniewaĔ ich stan po
dokonaniu pasywacji i aktywacji zaleĔy od implementacji.
Proces aktywacji jest obsäugiwany przez metody zwrotne cyklu Ĕycia komponentu. W prze-
ciwieþstwie do specyfikacji Enterprise JavaBeans 2.1 specyfikacja Enterprise JavaBeans 3.0 nie
nakäada na programistów klas bezstanowych komponentów sesyjnych obowiñzku imple-
mentowania metod zwrotnych, które nie sñ potrzebne (niezaimplementowane metody oczy-
wiĈcie nie sñ udostöpniane przez interfejs komponentu sesyjnego). Za poĈrednictwem metod
zwrotnych (oznaczonych stosownymi adnotacjami) programiĈci komponentów mogñ uzy-
skiwaè sygnaäy o zdarzeniach majñcych zwiñzek z cyklem Ĕycia ich komponentów. Przykäa-
dowo metoda oznaczona adnotacjñ
@javax.ejb.PostActivate
(jeĈli istnieje) jest wywoäywa-
na natychmiast po pomyĈlnym zakoþczeniu procesu aktywacji egzemplarza komponentu.
W ciele tej metody moĔna np. „wyzerowaè” wartoĈci pól przejĈciowych przypisujñc im war-
toĈci poczñtkowe. Metoda oznaczona adnotacjñ
@javax.ejb.PrePassivate
(jeĈli istnieje) jest
wywoäywana bezpoĈrednio przed przystñpieniem do pasywacji egzemplarza danego kom-
ponentu. Metody wyróĔnione tñ parñ adnotacji sñ szczególnie przydatne, jeĈli egzemplarze
naszego komponentu utrzymujñ poäñczenia z zasobami, które powinny byè zamykane lub
zwalniane przed przeprowadzeniem pasywacji oraz ponownie uzyskiwane lub odtwarzane
po aktywacji. PoniewaĔ egzemplarze stanowych komponentów sesyjnych w czasie pasywacji
sñ usuwane z pamiöci, otwarte poäñczenia z zasobami z natury rzeczy nie mogñ byè zacho-
wywane. Do wyjñtków naleĔñ zdalne referencje do pozostaäych komponentów oraz kontek-
stu sesji (reprezentowanego przez egzemplarz interfejsu
SessionContext
), które muszñ byè
zachowywane wraz z serializowanym stanem komponentu i odtwarzane w momencie jego
aktywowania. Specyfikacja Enterprise JavaBeans dodatkowo wymaga zachowywania w pro-
cesie pasywacji referencji do kontekstu Ĉrodowiska JNDI, interfejsów komponentu, usäugi
EntityManager
oraz obiektu
UserTransaction
.
Architektura Java EE Connector Architecture
Architektura Java EE Connector Architecture definiuje interfejs äñczñcy korporacyjne systemy
informacyjne (ang. Enterprise Information Systems — EIS) z systemami kontenerów Javy EE
(w tym kontenerami EJB i serwletów). EIS jest ogólnym terminem stosowanym w odniesieniu
do systemów informacyjnych, wäñcznie z serwerami relacyjnych baz danych, oprogramowa-
niem poĈredniczñcym (np. MQSeries lub SonicMQ), systemami w architekturze CORBA,
systemami ERP (np. SAP, PeopleSoft czy JD Edwards) oraz istniejñcymi systemami informa-
tycznymi (np. IMS czy CICS).
Zarz
édzanie zasobami
_
65
Java EE definiuje (oprócz architektury Enterprise JavaBeans) szereg standardowych interfej-
sów API dla rozwiñzaþ korporacyjnych, w tym takie interfejsy jak JDBC, JMS, JNDI, Java IDL
czy JavaMail. KaĔdy z tych interfejsów API oferuje niezaleĔne od producentów mechanizmy
dla ĈciĈle okreĈlonego rodzaju korporacyjnych systemów informatycznych. Przykäadowo in-
terfejs JDBC säuĔy do wymiany informacji z relacyjnymi bazami danych, JMS jest oprogra-
mowaniem poĈredniczñcym systemu przesyäania komunikatów, JNDI jest zbiorem usäug na-
zewnictwa i usäug katalogowych, JavaMail stworzono z myĈlñ o obsäudze poczty elektronicznej,
natomiast Java IDL jest interfejsem opracowanym z myĈlñ o architekturze CORBA. Obowiñzek
implementowania obsäugi tych interfejsów API jest gwarancjñ przenoĈnoĈci komponentów
EJB pomiödzy Ĉrodowiskami róĔnych producentów.
Mimo Ĕe interfejsy API dla rozwiñzaþ korporacyjnych w zaäoĔeniu majñ byè niezaleĔne od
producentów konkretnych rozwiñzaþ, produkty kryjñce siö za tymi interfejsami zawsze wy-
kazujñ cechy wäaĈciwe wyäñcznie dla ich producentów. Kiedy komponent EJB korzysta z tego
rodzaju interfejsu API, kontener EJB odpowiada za wäaĈciwe zarzñdzanie pulñ utrzymywa-
nych poäñczeþ z systemem EIS, wäñczanie tego systemu do obsäugiwanych transakcji, propa-
gowanie danych uwierzytelniajñcych itp. Wymienione zadania czösto wymagajñ od kontene-
ra EJB wspóäpracy z systemami EIS z wykorzystaniem technik, których nie przewidzieli lub
nie udokumentowali twórcy tych uniwersalnych interfejsów API. W efekcie kaĔdy producent
rozwiñzaþ pisanych w Javie EE musi tworzyè wäasny, niestandardowy kod wspóäpracujñcy
z ewentualnymi systemami EIS. W zwiñzku z tym producenci rozwiñzaþ Java EE wybierajñ
dla kaĔdego standardowego interfejsu API obsäugiwane systemy EIS. Takie podejĈcie ma
powaĔny wpäyw na zakres obsäugi poszczególnych systemów EIS przez producentów rozwiñ-
zaþ EJB — przykäadowo producent A moĔe obsäugiwaè poäñczenia za poĈrednictwem inter-
fejsu JDBC z systemami baz danych Oracle, natomiast producent B moĔe implementowaè ob-
säugö tylko poäñczeþ z bazami danych DB2.
Konektory JCA 1.5
Specyfikacja Enterprise JavaBeans 2.0 nakäadaäa na twórców komponentów EJB obowiñzek
implementowania obsäugi architektury Java EE Connector Architecture, która stanowiäa ogromny
krok na drodze do rozwiñzania opisywanych problemów. Z drugiej strony, proponowane
rozwiñzanie okazaäy siö niewystarczajñce. W szczególnoĈci nie udaäo siö rozwiñzaè problemu
braku obsäugi tzw. trybu wpychania (ang. push model) w systemach przesyäania komunika-
tów, co byäo o tyle istotne, Ĕe wiele systemów EIS (np. JMS) „wpychaäo” dane klientom mimo
braku odpowiednich Ĕñdaþ. Zarówno specyfikacja Enterprise JavaBeans 2.1, jak i specyfikacja
Enterprise JavaBeans 3.0 wymagajñ obsäugi architektury Java EE Connector Architecture 1.5,
która obsäuguje tryb wpychania. Z myĈlñ o obsäudze trybu wpychania twórcy architektury
JCA 1.5 wykorzystali model programowania komponentów sterowanych komunikatami.
W szczególnoĈci architektura JCA 1.5 definiuje interfejs kontener-konektor, który umoĔliwia
przetwarzanie komunikatów przychodzñcych (wysyäanych asynchronicznie przez system EIS)
przez komponenty sterowane komunikatami. Przykäadowo producent X mógäby opracowaè
konektor Java EE dla agenta Mail Delivery Agent (MDA) peäniñcy funkcjö oprogramowania
odpowiedzialnego za dostarczanie wiadomoĈci poczty elektronicznej. W ramach tego procesu
producent X moĔe wówczas zdefiniowaè interfejs nasäuchiwania komunikatów nazwany
EmailListenr
, który powinien byè implementowany przez komponenty poczty elektronicz-
nej sterowane komunikatami odpowiedzialne za przetwarzanie wiadomoĈci poczty elektro-
nicznej. Agent MDA „wpycha” otrzymywane z internetu wiadomoĈci poczty elektronicznej
66
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
do kontenera EJB, który z kolei deleguje otrzymywane komunikaty do egzemplarzy odpo-
wiednich komponentów sterowanych komunikatami. Programista aplikacji powinien nastöpnie
napisaè komponent poczty elektronicznej sterowany komunikatami oznaczony adnotacjñ
@javax.ejb.MessageDriven
i implementujñcy wspominany juĔ interfejs
com.producent.
EmailListener
. Ostatecznie opracowany i wdroĔony komponent poczty elektronicznej ste-
rowany komunikatami moĔe przetwarzaè komunikaty przychodzñce.
Us
ĥugi podstawowe
Istnieje wiele wartoĈciowych usäug opracowanych z myĈlñ o aplikacjach rozproszonych.
W niniejszej ksiñĔce szczegóäowo przeanalizujemy osiem najwaĔniejszych usäug nazywanych
usäugami podstawowymi (ang. primary services) z uwagi na koniecznoĈè ich implementowa-
nia przez wszystkie kompletne platformy Enterprise JavaBeans. Usäugi podstawowe oferujñ
mechanizmy w takich obszarach jak wspóäbieĔnoĈè, przetwarzanie transakcyjne, utrwalanie
danych, obsäuga obiektów rozproszonych, asynchroniczne przesyäanie komunikatów, licznik
czasowy, nazewnictwo i bezpieczeþstwo. Serwery EJB automatycznie zarzñdzajñ wszystkimi
wymienionymi usäugami podstawowymi. Takie rozwiñzanie zwalnia programistów aplikacji
z trudnego obowiñzku samodzielnego implementowania wszystkich lub czöĈci spoĈród wy-
mienionych rozwiñzaþ. Zamiast traciè czas na implementowanie tego rodzaju mechanizmów,
programiĈci mogñ siö koncentrowaè wyäñcznie na definiowaniu logiki aplikacji opisujñcej
okreĈlony wycinek dziaäalnoĈci biznesowej — za dostarczanie wszelkich niezbödnych usäug
na poziomie systemowym odpowiada serwer EJB. W kolejnych punktach omówimy poszcze-
gólne usäugi podstawowe i opiszemy wymagany zakres oferowanej funkcjonalnoĈci w ramach
tych usäug (zgodnie ze specyfikacjñ EJB).
Wspó
ĥbieżnoļë
ChociaĔ wspóäbieĔnoĈè (ang. concurrency) jako taka jest istotna z perspektywy programistów
komponentów wszystkich typów, w przypadku pewnych rodzajów komponentów ma nieco
inne znaczenie niĔ w przypadku innych typów.
Wspó
ĥbieżnoļë w pracy komponentów sesyjnych i encyjnych
Komponenty sesyjne nie obsäugujñ dostöpu wspóäbieĔnego. To ograniczenie jest w peäni uza-
sadnione, jeĈli uwzglödnimy faktyczny charakter stanowych i bezstanowych komponentów
sesyjnych. Stanowy komponent sesyjny jest rozszerzeniem pojedynczego klienta i pracuje
wyäñcznie w jego imieniu. W zwiñzku z tym oferowanie wspóäbieĔnego dostöpu do tego ro-
dzaju komponentów caäkowicie mijaäoby siö z ich wäaĈciwym przeznaczeniem, poniewaĔ i tak
sñ wykorzystywane przez te aplikacje klienckie, które je utworzyäy. TakĔe bezstanowe kom-
ponenty sesyjne nie muszñ oferowaè wspóäbieĔnoĈci, poniewaĔ i tak nie utrzymujñ stanu,
który wymagaäby wspóädzielenia (wspóäbieĔnego dostöpu). Zasiög operacji wykonywanych
przez bezstanowe komponenty sesyjne ogranicza siö do zasiögu odpowiednich wywoäaþ metod.
PoniewaĔ ani stanowe, ani bezstanowe komponenty sesyjne nie reprezentujñ danych wspóä-
dzielonych, w ich przypadku serwer EJB nie musi implementowaè usäug zarz
ñdzajñcych
wspóäbieĔnoĈciñ.
Us
ĥugi podstawowe
_
67
PoniewaĔ za obsäugö wspóäbieĔnoĈci odpowiadajñ serwery EJB, metody samych komponentów
nie muszñ gwarantowaè bezpieczeþstwa przetwarzania wielowñtkowego. W rzeczywistoĈci
specyfikacja Enterprise JavaBeans wröcz zakazuje programistom komponentów EJB stosowa-
nia säowa kluczowego
synchronized
. Zakaz uĔywania w kodzie podstawowych konstrukcji
synchronizujñcych pracö wñtków skutecznie uniemoĔliwia programistom podejmowanie prób
samodzielnego sterowania synchronizacjñ i — tym samym — przekäada siö na wiökszñ wy-
dajnoĈè egzemplarzy komponentów w czasie wykonywania. Co wiöcej, specyfikacja Enter-
prise JavaBeans wprost zakazuje komponentom tworzenia wäasnych wñtków. Innymi säowy,
programista nie moĔe z poziomu swoich komponentów tworzyè nowych wñtków. Zacho-
wywanie peänej kontroli nad komponentem naleĔy do kontenera EJB, który musi wäaĈciwie
zarzñdzaè wspóäbieĔnoĈciñ, przetwarzaniem transakcyjnym oraz utrwalaniem danych.
DowolnoĈè w kwestii tworzenia wñtków przez programistö komponentu uniemoĔliwiäaby
kontenerowi nie tylko Ĉledzenie dziaäaþ komponentu, ale takĔe wäaĈciwe zarzñdzanie pod-
stawowymi usäugami.
Komponenty encyjne reprezentujñ dane wspóädzielone i jako takie mogñ byè przedmiotem
dostöpu wspóäbieĔnego. Komponenty encyjne zaliczamy do tzw. komponentów wspóädzie-
lonych. Przykäadowo w systemie EJB linii Ĕeglugowych Titan Cruises sñ reprezentowane trzy
statki: Paradise, Utopia i Valhalla. Komponent encyjny Ship reprezentujñcy statek Utopia w do-
wolnym momencie moĔe byè adresatem Ĕñdaþ generowanych przez setki aplikacji klienckich.
Aby wspóäbieĔny dostöp do komponentu encyjnego byä moĔliwy, mechanizm odpowiedzialny
za utrwalanie danych musi odpowiednio chroniè dane reprezentowane przez taki kompo-
nent wspóädzielony (mimo nastöpujñcego jednoczeĈnie dostöpu wielu aplikacji klienckich do
jednego logicznego komponentu encyjnego).
Specyfikacja Java Persistence przewiduje, Ĕe kontener odpowiedzialny za ochronö wspóä-
dzielonych danych komponentów encyjnych powinien tworzyè po jednej kopii egzemplarza
komponentu encyjnego dla kaĔdej z wykonywanych transakcji. WäaĈnie istnienie migawki
danej encji dla kaĔdej transakcji umoĔliwia prawidäowñ i bezpiecznñ obsäugö wspóäbieĔnego,
wielowñtkowego dostöpu. Warto siö wiöc zastanowiè, jak to moĔliwe, Ĕe kontener skutecznie
chroni komponenty encyjne przed faäszywymi odczytami oraz próbami jednoczesnej aktuali-
zacji przez wiele transakcji. Jednym z moĔliwych rozwiñzaþ jest stosowanie strategii tzw.
wspóäbieĔnoĈci optymistycznej z wykorzystaniem prostego mechanizmu pól reprezentujñ-
cych wersje. Innym rozwiñzaniem jest uĔycie opcji
SERIALIZED
dla poziomu izolacji interfejsu
JDBC. Implementacje tworzone przez rozmaitych producentów mogñ wykorzystywaè wäasne,
niestandardowe mechanizmy bezpoĈredniego blokowania dostöpu do informacji na poziomie
bazy danych. Wszystkie te zagadnienia zostanñ szczegóäowo omówione w rozdziale 16.
Wspó
ĥbieżnoļë w pracy komponentów sterowanych komunikatami
W przypadku komponentów sterowanych komunikatami okreĈlenie wspóäbieĔnoĈè odnosi
siö do jednoczesnego przetwarzania wiöcej niĔ jednego komunikatu. Gdyby komponent ste-
rowany komunikatami mógä w danej chwili przetwarzaè tylko jeden komunikat, jego przy-
datnoĈè dla rzeczywistych aplikacji byäaby znikoma, poniewaĔ systemy zäoĔone z takich
komponentów nie mogäyby sobie radziè z duĔymi obciñĔeniami (wyraĔanymi w liczbie ko-
munikatów generowanych w okreĈlonych przedziaäach czasowych). Na rysunku 3.4 przed-
stawiono sytuacjö, w której do przykäadowego systemu EJB docierajñ trzy komunikaty wyge-
nerowane jednoczeĈnie przez trzy róĔne aplikacje klienckie — trzy egzemplarze pojedynczego
komponentu JMS-MDB, które zarejestrowaäy swoje zainteresowanie tego rodzaju komuni-
katami, mogñ jednoczeĈnie przetwarzaè wspomniane komunikaty.
68
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Rysunek 3.4. Przetwarzanie wspó
äbieĔne z wykorzystaniem komponentów sterowanych komunikatami
TakĔe te komponenty sterowane komunikatami, które implementujñ inne interfejsy API niĔ JMS,
mogñ korzystaè z tych samych usäug wspóäbieĔnoĈci co komponenty JMS-MDB. Egzemplarze
wszystkich rodzajów komponentów sterowanych komunikatami sñ skäadowane w puli i wy-
korzystywane do wspóäbieĔnego przetwarzania komponentów przychodzñcych — dziöki temu
istnieje moĔliwoĈè jednoczesnej obsäugi setek lub wröcz tysiöcy komunikatów generowanych
przez aplikacje klienckie
1
.
Transakcje
Transakcja jest jednostkñ pracy lub zbiorem zadaþ wykonywanych sekwencyjnie w odpo-
wiedzi na jedno Ĕñdanie. Transakcje sñ atomowe, co oznacza, Ĕe pojedynczñ transakcjö moĔ-
na uznaè za prawidäowo wykonanñ wtedy i tylko wtedy, gdy uda siö zrealizowaè wszystkie
zadania skäadajñce siö na tö transakcjö. W poprzednim rozdziale wielokrotnie mówiliĈmy
o komponencie EJB TravelAgent w kontekĈcie sposobu kontrolowania przez komponenty sesyjne
interakcji z pozostaäymi komponentami. PoniĔej przedstawiono metodö
bookPassage()
, którñ
opisano w rozdziale 2.:
public Reservation bookPassage(CreditCardDO card, double price)
throws IncompleteConversationalState {
if (customer == null || cruise == null || cabin == null) {
throw new IncompleteConversationalState( );
}
try {
Reservation reservation =
new Reservation(customer,cruise,cabin,price,new Date( ));
entityManager.persist(reservation);
process.byCredit(customer,card,price);
return reservation;
} catch(Exception e) {
throw new EJBException(e);
}
}
Metoda
bookPassage()
realizuje dwa zadania, które muszñ byè wykonane albo razem, albo
wcale — tymi zadaniami jest odpowiednio utworzenie nowego egzemplarza Reservation oraz
przetworzenie päatnoĈci. Kiedy komponent EJB TravelAgent jest wykorzystywany do rezer-
wacji miejsca w kajucie dla nowego pasaĔera, musi zostaè skutecznie przeprowadzone za-
1
W praktyce jednoczesne przetwarzanie czegokolwiek w sytuacji, gdy nie dysponujemy wieloma procesorami,
jest bardzo trudne, jednak na poziomie pojöciowym nasze stwierdzenie jest prawdziwe. Wiele wñtków w ramach
tej samej wirtualnej maszyny Javy lub w ramach wielu maszyn wirtualnych korzystajñcych z tego samego
procesora (fizycznego ukäadu obliczeniowego) mogñ skutecznie imitowaè przetwarzanie wspóäbieĔne.
Us
ĥugi podstawowe
_
69
równo pobranie stosownej kwoty z karty kredytowej pasaĔera, jak i utworzenie nowej encji
reprezentujñcej samñ rezerwacjö. Gdyby inny komponent EJB, ProcessPayment, pobraä kwotö
z karty kredytowej pasaĔera w sytuacji, gdy próba utworzenia nowej encji Reservation zakoþ-
czyäa siö niepowodzeniem, naleĔaäoby to dziaäanie uznaè za niewäaĈciwe. Podobnie nie po-
winniĈmy tworzyè nowej rezerwacji, jeĈli nie uda siö pobraè stosownej kwoty z karty kredytowej
pasaĔera. Oznacza to, Ĕe serwer EJB musi uwaĔnie monitorowaè tego rodzaju transakcje, aby
zagwarantowaè wäaĈciwe wykonywanie wszystkich zadaþ.
Transakcje sñ zarzñdzane automatycznie, zatem programiĈci komponentów EJB nie muszñ
stosowaè Ĕadnych interfejsów API odpowiedzialnych za zarzñdzanie zaangaĔowaniem two-
rzonych komponentów w przetwarzanie transakcyjne. Aby zasygnalizowaè serwerowi EJB
sposób, w jaki powinien zarzñdzaè komponentem w czasie dziaäania, wystarczy w czasie
wdraĔania zadeklarowaè odpowiednie atrybuty transakcyjne. Okazuje siö jednak, Ĕe specyfi-
kacja EJB definiuje mechanizm umoĔliwiajñcy bezpoĈrednie zarzñdzanie transakcjami tym
komponentom, w przypadku których jest to niezbödne. Atrybuty transakcyjne ustawiane
w czasie wdraĔania, techniki zarzñdzania transakcjami wprost przez programistów kompo-
nentów EJB oraz pozostaäe zagadnienia zwiñzane z przetwarzaniem transakcyjnym zostanñ
omówione w rozdziale 16.
Trwa
ĥoļë
Komponenty encyjne reprezentujñ zachowania i dane wäaĈciwe dla osób, miejsc lub przed-
miotów. W przeciwieþstwie do komponentów sesyjnych i komponentów sterowanych ko-
munikatami komponenty encyjne majñ charakter trwaäy, co oznacza, Ĕe ich stan jest zapisy-
wany (utrwalany) w bazie danych. Mechanizm utrwalania umoĔliwia zachowywanie encji
w sposób umoĔliwiajñcy uzyskiwanie dostöpu zarówno do zachowaþ, jak i do danych kom-
ponentów encyjnych w dowolnym czasie (bez koniecznoĈci samodzielnego odzyskiwania
tych zachowaþ i danych w razie ewentualnej awarii).
Java Persistence
W specyfikacji Enterprise JavaBeans 3.0 caäkowicie zweryfikowano dotychczasowe podejĈcie
do problemu utrwalania — zdecydowano siö nawet na wyäñczenie tej problematyki do od-
röbnej, przebudowanej specyfikacji Java Persistence. O ile specyfikacja Enterprise JavaBeans
2.1 proponowaäa model, w którym utrwalanie byäo realizowane na poziomie komponentów,
zgodnie z nowñ specyfikacjñ Java Persistence trwaäe komponenty encyjne majñ postaè zwy-
käych obiektów Javy (nazywanych obiektami POJO). Encje moĔna tworzyè poza Ĉrodowi-
skiem kontenera EJB. Sam proces ich tworzenia niczym siö nie róĔni od procesów tworzenia
wszystkich innych obiektów Javy z wykorzystaniem standardowego operatora
new()
. Co
wiöcej, komponent encyjny moĔe byè w dowolnym momencie wäñczany do kolekcji kompo-
nentów zarzñdzanych przez kontener lub wykluczany z tego zbioru. Za wiñzanie egzempla-
rzy komponentów encyjnych z pamiöciñ trwaäñ (najczöĈciej bazñ danych) odpowiada usäuga
EntityManager
. Usäuga
EntityManager
oferuje metody umoĔliwiajñce tworzenie, odnajdy-
wanie, odczytywanie, usuwanie i aktualizowanie komponentów encyjnych. Po poäñczeniu
egzemplarza komponentu encyjnego z pamiöciñ trwaäñ kontener EJB odpowiada za zarzñ-
dzanie trwaäym stanem tego komponentu i automatycznñ synchronizacjö z odpowiednim
Ēródäem danych.
70
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Szczególnie interesujñcym aspektem modelu proponowanego w specyfikacji Java Persistence
jest moĔliwoĈè odäñczania egzemplarzy komponentów encyjnych od kontenera EJB. Egzem-
plarze komponentów EJB z reguäy sñ odäñczane od kontenera w chwili zakoþczenia wyko-
nywania bieĔñcej transakcji. Warto pamiötaè, Ĕe tak odäñczone egzemplarze moĔna swobod-
nie przesyäaè za poĈrednictwem sieci zdalnym aplikacjom klienckim lub wröcz zapisywaè na
dysku. Stan tego rodzaju egzemplarzy moĔe byè modyfikowany, a same egzemplarze kompo-
nentów moĔna ponownie äñczyè z kontenerem EJB za pomocñ metody
EntityManager.merge()
.
W momencie ponownego äñczenia egzemplarza komponentu encyjnego z kontenerem EJB
wszelkie zmiany dokonane na danym komponencie automatycznie sñ synchronizowane
z zawartoĈciñ pamiöci trwaäej. Nowy model utrwalania danych umoĔliwia programistom
komponentów EJB rezygnacjö ze starej koncepcji obiektów transferu danych (ang. Data
Transfer Object), co w znacznym stopniu upraszcza architekturö konstruowanych aplikacji.
Szczegóäowe omówienie tego zagadnienia moĔna znaleĒè w rozdziale 5.
Utrwalanie obiektowo-relacyjne
Utrwalanie obiektowo-relacyjne (ang. object-to-relational — O/R) wiñĔe siö z koniecznoĈciñ
odwzorowywania stanu komponentów encyjnych w tabelach i kolumnach relacyjnej bazy
danych. PoniewaĔ relacyjne bazy danych sñ wykorzystywane przez 99 procent aplikacji ko-
rzystajñcych z baz danych, grupa ekspertów zaangaĔowana w prace nad nowñ specyfikacjñ
Enterprise JavaBeans (EJB 3.0 Expert Group) ustaliäa, Ĕe opracowanie mechanizmu odwzo-
rowaþ obiektowo-relacyjnych bödzie duĔo lepszym rozwiñzaniem niĔ podejmowanie skaza-
nych na niepowodzenie prób tworzenia jednej, uniwersalnej architektury utrwalania. Wsku-
tek tej decyzji powstaäa specyfikacja Java Persistence obejmujñca bogaty zbiór mechanizmów
odpowiedzialnych za odwzorowywanie komponentów encyjnych w relacyjnych bazach da-
nych z uwzglödnieniem takich technik jak dziedziczenie, odwzorowania w wielu tabelach,
zarzñdzanie wersjami czy obsäuga rozszerzonego jözyka zapytaþ EJBQL. PoniewaĔ odwzo-
rowania obiektowo-relacyjne sñ precyzyjnie definiowane przez konkretnñ specyfikacjö, wspóä-
czesne aplikacje EJB oferujñ duĔo wiökszñ przenoĈnoĈè pomiödzy rozwiñzaniami róĔnych
producentów, poniewaĔ w znacznym stopniu wyeliminowano koniecznoĈè stosowania me-
tadanych wäaĈciwych dla poszczególnych produktów.
Przeanalizujmy teraz prosty przykäad stosowania techniki odwzorowaþ obiektowo-relacyjnych
w praktyce. W systemie informatycznym linii Ĕeglugowych Titan Cruises klasa
Cabin
modeluje
kajutö na statku. Klasa
Cabin
definiuje trzy pola skäadowe:
name
,
deckLevel
oraz
id
. Definicjö
klasy
Cabin
przedstawiono poniĔej:
@Entity
@Table(name="CABIN")
public class Cabin {
private int id;
private String name;
private int deckLevel;
@Column(name="NAME")
public String getName( ) { return name; }
public void setName(String str) { name = str; }
@Column(name="DECK_LEVEL")
public int getDeckLevel( ) { return deckLevel; }
public void setDeckLevel(int level) { deckLevel = level; }
Us
ĥugi podstawowe
_
71
@Id
@Column(name="ID")
public int getId( ) { return id; }
public void setId(int id) { this.id = id; }
}
W prezentowanym przykäadzie metody akcesorów reprezentujñ pola komponentu encyjnego
zarzñdzane przez kontener EJB. Skoro stosujemy mechanizm odwzorowaþ obiektowo-rela-
cyjnych, moĔemy przyjñè, Ĕe pola komponentu encyjnego odpowiadajñ kolumnom relacyjnej
bazy danych. Metadane opisujñce odwzorowania obiektowo-relacyjne naleĔy definiowaè
w formie adnotacji poprzedzajñcych zarówno metody akcesorów (
@Column
oraz
@Id
), jak i klasö
komponentu (
@Table
). Przykäadowo pole
deckLevel
klasy
Cabin
jest odwzorowywane w ko-
lumnie
DECK_LEVEL
tabeli nazwanej
CABIN
i wchodzñcej w skäad relacyjnej bazy danych linii
Titan Cruises. Na rysunku 3.5 przedstawiono graficzny schemat tego odwzorowania.
Rysunek 3.5. Schemat odwzorowania obiektowo-relacyjnego komponentów encyjnych
Kiedy pola komponentu encyjnego zostanñ juĔ odwzorowane w relacyjnej bazie danych,
kontener bierze na siebie odpowiedzialnoĈè za utrzymywanie zgodnoĈci stanu danego eg-
zemplarza komponentu z zawartoĈciñ odpowiednich tabel bazy danych. Proces utrzymywa-
nia tej zgodnoĈci bywa nazywany synchronizacjñ stanu egzemplarza komponentu. W przy-
padku klasy
Cabin
egzemplarze komponentu encyjnego sñ odwzorowywane w odröbnych
wierszach tabeli
CABIN
relacyjnej bazy danych. Oznacza to, Ĕe modyfikacja egzemplarza
komponentu encyjnego Cabin wymaga jego zapisania we wäaĈciwym wierszu bazy danych.
Warto pamiötaè, Ĕe niektóre z komponentów sñ odwzorowywane w wiöcej niĔ jednej tabeli
bazy danych. Tego rodzaju odwzorowania sñ znacznie bardziej skomplikowane i czösto wy-
magajñ stosowania miödzy innymi zäñczeþ SQL-a i wielokrotnych aktualizacji — zäoĔone
odwzorowania obiektowo-relacyjne przeanalizujemy w dalszej czöĈci tej ksiñĔki.
Specyfikacja Java Persistence dodatkowo definiuje pola relacji komponentów encyjnych, które
umoĔliwiajñ wchodzenie tego rodzaju komponentów w relacje „jeden do jednego”, „jeden do
wielu” oraz „wiele do wielu” z pozostaäymi komponentami. Co wiöcej, komponenty encyjne
same mogñ utrzymywaè kolekcje innych komponentów encyjnych lub pojedyncze referencje.
Model Java Persistence szczegóäowo omówiono w rozdziaäach od 5. do 10.
72
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Obiekty rozproszone
Kiedy mówimy o interfejsach komponentów oraz innych klasach i interfejsach technologii EJB
wykorzystywanych przez oprogramowanie klienckie, mamy na myĈli perspektywö klienta
danego systemu EJB. Perspektywa klienta EJB (ang. EJB client view) nie obejmuje egzempla-
rzy klas komponentów sesyjnych, kontenera EJB, mechanizmu wymiany egzemplarzy ani
Ĕadnych innych szczegóäów zwiñzanych z implementacjñ poszczególnych komponentów se-
syjnych. Z perspektywy klientów zdalnych komponent jest definiowany przez interfejs zdalny
lub interfejs punktu koþcowego
2
. Wszystkie inne elementy, wäñcznie z mechanizmem wyko-
rzystywanym do obsäugi obiektów rozproszonych, sñ niewidoczne. JeĈli wykorzystywany
serwer EJB prawidäowo obsäuguje perspektywö danego klienta EJB, w komunikacji pomiödzy
tymi wözäami moĔe byè stosowany dowolny protokóä obiektów rozproszonych. Specyfikacja
Enterprise JavaBeans 3.0 mówi, Ĕe kaĔdy serwer EJB musi obsäugiwaè protokóä Java RMI-IIOP,
co nie oznacza, Ĕe serwery EJB nie mogñ obsäugiwaè takĔe innych protokoäów (w tym inter-
fejsu Java RMI API oraz protokoäu CORBA IIOP). Specyfikacja EJB 3.0 dodatkowo nakäada na
producentów serwerów obowiñzek implementowania obsäugi protokoäu SOAP 1.2 za po-
Ĉrednictwem interfejsu JAX-RPC API.
NiezaleĔnie od wykorzystywanego protokoäu serwer EJB musi obsäugiwaè Ĕñdania klientów
Javy z wykorzystaniem odpowiedniego interfejsu API tych klientów, zatem stosowany pro-
tokóä powinien oferowaè moĔliwoĈè odwzorowywania do modelu programowania Java RMI-IIOP
lub JAX-RPC. Na rysunku 3.6 przedstawiono przykäad interfejsu EJB API jözyka Java obsäu-
giwanego przez róĔne protokoäy obiektów rozproszonych.
Rysunek 3.6. Perspektywa klienta systemu EJB obs
äugiwana przez róĔne protokoäy
Specyfikacja Enterprise JavaBeans przewiduje moĔliwoĈè uzyskiwania przez oprogramowanie
klienckie napisane w jözykach innych niĔ Java dostöpu do komponentów EJB (pod warun-
kiem, Ĕe producent serwera EJB zaimplementuje odpowiednie mechanizmy). Przykäadem ta-
kiego rozwiñzania jest mechanizm odwzorowaþ EJB-CORBA opracowany przez firmö Sun
3
.
Dokument opublikowany przez Sun Microsystems opisuje jözyk definiowania interfejsów
architektury CORBA (ang. CORBA Interface Definition Language — CORBA IDL), za pomocñ
którego moĔna uzyskiwaè dostöp do komponentów EJB z poziomu klientów technologii
CORBA. Aplikacje klienckie architektury CORBA moĔna pisaè w dowolnych jözykach progra-
mowania, wäñcznie z takimi jözykami jak C++, Smalltalk, Ada czy COBOL. Wspomniany me-
chanizm odwzorowujñcy dodatkowo obejmuje szczegóäowe rozwiñzania w zakresie obsäugi
2
Nieco inaczej jest w przypadku komponentów encyjnych, poniewaĔ egzemplarze klas tego rodzaju kompo-
nentów mogñ byè odäñczane od kontenera i wysyäane do zdalnego klienta (pod warunkiem, Ĕe wspomniane
klasy implementujñ interfejs
java.io.Serializable
).
3
Enterprise JavaBeans™ to CORBA Mapping, Version 1.1, Sanjeev Krishnan, Sun Microsystems, 1999.
Us
ĥugi podstawowe
_
73
perspektywy klientów Java EJB, odwzorowaþ systemu nazewnictwa architektury CORBA
w system nazewnictwa serwerów EJB oraz rozproszonymi transakcjami obejmujñcymi swoim
zasiögiem zarówno obiekty CORBA, jak i komponenty EJB. Innym ciekawym przykäadem
jest odwzorowanie EJB-SOAP zbudowane na bazie technologii JAX-RPC. Odwzorowanie
EJB-SOAP umoĔliwia aplikacjom klienckim SOAP napisanym w takich jözykach jak Visual
Basic .NET, C# czy Perl uzyskiwanie dostöpu do bezstanowych komponentów sesyjnych. Na
rysunku 3.7 przedstawiono moĔliwe rozwiñzania w zakresie uzyskiwania dostöpu do serwera
EJB z poziomu innych obiektów rozproszonych.
Rysunek 3.7. Komponent EJB udost
öpniany róĔnym rozproszonym aplikacjom klienckim
Asynchroniczne przesy
ĥanie komunikatów
Przed wydaniem specyfikacji Enterprise JavaBeans 2.0 asynchroniczne przesyäanie komuni-
katów nie byäo zaliczane do zbioru usäug podstawowych, poniewaĔ implementacja obsäugi
tego rodzaju komunikatów nie byäa konieczna do stworzenia kompletnej platformy EJB.
Z drugiej strony, wprowadzenie komponentów sterowanych komunikatami spowodowaäo
istotny wzrost znaczenia asynchronicznego przesyäania komunikatów za pomocñ systemu
JMS, które ostatecznie zostaäo uznane za jednñ z usäug podstawowych.
Obsäuga przesyäania komunikatów wymaga od kontenera EJB implementowania niezawod-
nych mechanizmów kierowania komunikatów pochodzñcych od oprogramowania klienckiego
JMS do wäaĈciwych komponentów JMS-MDB. Niezawodne kierowanie komunikatów do
miejsc docelowych wymaga czegoĈ wiöcej niĔ semantyki podobnej do tej znanej z poczty
elektronicznej czy nawet interfejsu JMS API. Systemy korporacyjne z natury rzeczy wyma-
gajñ solidnych mechanizmów przekazywania komunikatów, co w przypadku systemu JMS
wiñĔe siö z koniecznoĈciñ ponownego wysyäania komunikatów, których dostarczenie okazaäo siö
niemoĔliwe
4
. Co wiöcej, komunikaty w systemach EJB mogñ mieè charakter trwaäy, co ozna-
cza, Ĕe mogñ byè skäadowane na dysku lub w bazie danych do momentu, w którym bödzie je
moĔna dostarczyè do wäaĈciwych adresatów. Komunikaty trwaäe muszñ byè zachowywane
4
WiökszoĈè producentów kontenerów EJB ogranicza maksymalnñ liczbö prób ponownego wysyäania niedo-
starczonych komunikatów. JeĈli liczba takich prób przekroczyäa okreĈlony próg, odpowiedni komunikat
moĔna umieĈciè w specjalnym repozytorium „martwych komunikatów”, gdzie mogñ byè przeglñdane przez
administratora.
74
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
mimo ewentualnych awarii systemowych — komunikaty trwaäe muszñ zostaè dostarczone
nawet wówczas, jeĈli awarii ulegnie serwer EJB (choèby miaäo to nastñpiè po ponownym
uruchomieniu tego serwera). Co ciekawe, przesyäanie komunikatów w systemie EJB ma cha-
rakter transakcyjny. Oznacza to, Ĕe jeĈli komponent JMS-MDB nie zdoäa prawidäowo przetwo-
rzyè otrzymanego komunikatu, automatycznie trzeba bödzie przerwaè caäñ transakcjö i wymusiè
na kontenerze EJB ponowne dostarczenie tego samego komunikatu do innego egzemplarza
komponentu sterowanego komunikatami.
Okazuje siö, Ĕe komunikaty JMS mogñ byè wysyäane takĔe przez komponenty sterowane
komunikatami, bezstanowe komponenty sesyjne oraz komponenty encyjne. W niektórych przy-
padkach moĔliwoĈè wysyäania komunikatów jest w przypadku standardowych komponentów
Enterprise JavaBeans równie istotna jak w przypadku komponentów JMS-MDB — obsäuga
obu rozwiñzaþ z reguäy jest implementowana w bardzo podobny sposób.
Us
ĥuga licznika czasowego EJB
Usäuga licznika czasowego EJB (ang. EJB Timer Service) moĔe säuĔyè do konstruowania har-
monogramów wysyäania powiadomieþ do komponentów EJB w okreĈlonych odstöpach czasu.
Liczniki czasowe znajdujñ zastosowanie w wielu róĔnych aplikacjach. Przykäadowo systemy
bankowe mogñ wykorzystywaè tego rodzaju liczniki w roli zabezpieczeþ kredytów hipotecz-
nych, a konkretnie mechanizmu weryfikujñcego terminowoĈè dokonywanych späat. System ob-
säugujñcy handel akcjami na gieädzie papierów wartoĈciowych moĔe korzystaè z tej usäugi do
ustanawiania okresów waĔnoĈci skäadanych zleceþ. System obsäugujñcy roszczenia klientów
firmy ubezpieczeniowej moĔe stosowaè liczniki czasowe do automatycznego inicjowania
okresowych kontroli pod kñtem ewentualnych wyäudzeþ. Liczniki czasowe mogñ byè stoso-
wane we wszelkich aplikacjach wymagajñcych samokontroli i przetwarzania wsadowego.
Liczniki czasowe mogñ byè ustawiane w komponentach encyjnych, bezstanowych komponen-
tach sesyjnych oraz komponentach sterowanych komunikatami. Warto pamiötaè,
Ĕe kompo-
nenty sesyjne i encyjne same ustawiajñ liczniki czasowe. Przykäadowo, w chwili przyznania
kredytu hipotecznego komponent encyjny reprezentujñcy ten kredyt moĔe ustawiè licznik
umoĔliwiajñcy weryfikacjö uregulowania kolejnej raty, który bödzie zerowany po kaĔdej
prawidäowej wpäacie. Niektóre kontenery Enterprise JavaBeans oferujñ obsäugö liczników
czasowych wykorzystywanych takĔe przez komponenty sterowane komunikatami, jednak
w tego rodzaju przypadkach konfiguracja nastöpuje w czasie wdraĔania, a same liczniki odpo-
wiadajñ za przetwarzanie wsadowe w okreĈlonych odstöpach czasu. Usäugö licznika czasowego
szczegóäowo omówimy w rozdziale 13.
Nazewnictwo
Wszystkie usäugi nazewnicze odpowiadajñ za realizacjö podobnych dziaäaþ — oferujñ swoim
klientom mechanizmy uäatwiajñce lokalizowanie obiektów lub zasobów rozproszonych. Efek-
tywna realizacja tego zadania wymaga od usäug nazewniczych dwóch rzeczy: wiñzania obiek-
tów oraz udostöpniania interfejsu API dla operacji wyszukiwania. Wiñzanie obiektów (ang.
object binding) polega na przypisywaniu obiektom rozproszonym nazw wyraĔonych w jözyku
naturalnym lub identyfikatorów. Przykäadowo obiektowi
TravelAgentRemote
moĔna przy-
pisaè nazwö TravelAgentRemote lub agent. Przypisana nazwa bñdĒ identyfikator w praktyce
peäni funkcjö wskaĒnika bñdĒ indeksu okreĈlonego obiektu rozproszonego. Interfejs API
Us
ĥugi podstawowe
_
75
wyszukiwania oferuje oprogramowaniu klienckiemu dostöp do elementów funkcjonalnoĈci
stosowanego systemu nazewnictwa. Najkrócej mówiñc, interfejsy wyszukiwania umoĔliwiajñ
klientom äñczenie siö z usäugami rozproszonymi oraz Ĕñdanie zdalnych referencji do po-
trzebnych obiektów.
Specyfikacja Enterprise JavaBeans wymusza na producentach kontenerów EJB stosowanie
interfejsu JNDI w roli API Ĕñdania obsäugujñcego wyszukiwania komponentów generowanego
przez aplikacje klienckie Javy. Interfejs JNDI obsäuguje niemal wszystkie rodzaje usäug na-
zewnictwa i katalogów. Mimo Ĕe wielu programistów uwaĔa ten interfejs za nadmiernie
skomplikowany, jego wywoäania na poziomie aplikacji Javy EE z reguäy majñ doĈè prostñ
formö. Aplikacje klienckie Javy mogñ wykorzystywaè interfejs JNDI zarówno do inicjowania
poäñczeþ z serwerem EJB, jak i do lokalizowania konkretnych komponentów EJB. Przykäa-
dowo poniĔszy fragment kodu demonstruje sposób, w jaki za pomocñ interfejsu JNDI API
moĔna zlokalizowaè i uzyskaè referencjö do komponentu EJB TravelAgent:
javax.naming.Context jndiContext = new javax.naming.InitialContext( );
Object ref = jndiContext.lookup("TravelAgentRemote");
TravelAgentRemote agent = (TravelAgentRemote)
PortableRemoteObject.narrow(ref, TravelAgentRemote.class);
Reservation res = agent.bookPassage(...);
WäaĈciwoĈci przekazywane za poĈrednictwem parametrów konstruktora klasy
InitialContext
sygnalizujñ interfejsowi JNDI API, gdzie naleĔy szukaè serwera EJB i który sterownik JNDI
zaäadowaè. Metoda
Context.lookup()
okreĈla na potrzeby usäugi JNDI nazwö obiektu, który
ma zostaè zwrócony przez wskazany wczeĈniej serwer EJB. W tym przypadku interesuje nas
interfejs zdalny komponentu EJB TravelAgent. Kiedy juĔ bödziemy dysponowali wspomnianym
interfejsem, bödziemy mogli wywoäywaè metody obsäugujñce takie operacje jak rezerwowanie
miejsc w kajutach.
Istnieje wiele róĔnych rodzajów usäug katalogowych i nazewniczych — producenci kontene-
rów EJB mogñ co prawda swobodnie wybieraè te rozwiñzania, które w najwiökszym stopniu
speäniajñ ich wymagania, jednak wszystkie serwery muszñ dodatkowo obsäugiwaè usäugö
nazewniczñ architektury CORBA.
Bezpiecze
ħstwo
Serwery Enterprise JavaBeans mogñ obsäugiwaè aĔ trzy rodzaje zabezpieczeþ:
Uwierzytelnianie
NajproĈciej mówiñc, uwierzytelnianie polega na potwierdzaniu toĔsamoĈci danego uĔyt-
kownika. Najbardziej popularnñ formñ uwierzytelniania jest ekran logowania, w którym
uĔytkownik musi wpisaè swoje nazwö i hasäo. UĔytkownik moĔe korzystaè z danego
systemu dopiero po akceptacji podanych przez niego danych w systemie uwierzytelniajñ-
cym. W procesie uwierzytelniania moĔna wykorzystywaè takĔe karty identyfikujñce, karty
z paskiem magnetycznym, certyfikaty bezpieczeþstwa i wszelkie inne formy identyfikacji.
ChociaĔ mechanizmy uwierzytelniajñce majñ na celu przede wszystkim zabezpieczanie
systemu przed dostöpem osób nieuprawnionych, najwiökszñ niedoskonaäoĈciñ tego rodzaju
rozwiñzaþ jest brak kontroli nad dostöpem do zasobów systemu przez raz uwierzytelnionego
uĔytkownika.
76
_
Rozdzia
ĥ 3. Zarzédzanie zasobami i usĥugi podstawowe
Autoryzacja
Autoryzacja (kontrola dostöpu) polega na wymuszaniu stosowania okreĈlonej polityki
bezpieczeþstwa okreĈlajñcej, co poszczególni uĔytkownicy mogñ, a czego nie mogñ robiè
w danym systemie. Kontrola dostöpu daje nam pewnoĈè, Ĕe uĔytkownicy uzyskujñ do-
stöp tylko do tych zasobów, które sñ im rzeczywiĈcie potrzebne. Autoryzacja umoĔliwia
nie tylko ograniczanie dostöpu do podsystemów, danych lub obiektów biznesowych, ale
teĔ monitorowanie ogólnych zachowaþ. Przykäadowo, niektórzy uĔytkownicy mogñ mieè
prawo aktualizacji informacji, podczas gdy pozostali mogñ te informacje tylko przeglñdaè.
Bezpieczna komunikacja
Kanaäy komunikacyjne äñczñce klienta z serwerem doĈè czösto muszñ gwarantowaè od-
powiedni poziom bezpieczeþstwa. Kanaä komunikacyjny moĔna zabezpieczyè, np. szy-
frujñc dane przesyäane pomiödzy serwerem a klientem. W takim przypadku wszystkie
przesyäane komunikaty sñ kodowane w sposób uniemoĔliwiaj
ñcy ich odczytywanie lub
modyfikowanie przez nieautoryzowanych uĔytkowników. Tego rodzaju rozwiñzania
z reguäy wiñĔñ siö z koniecznoĈciñ wymiany pomiödzy klientem a serwerem kluczy krypto-
graficznych. Klucze umoĔliwiajñ uprawnionym odbiorcom komunikatów dekodowanie
i odczytywanie ich treĈci.
Zagadnienia zwiñzane z bezpieczeþstwem szczegóäowo omówimy w rozdziale 17.
Us
ĥugi podstawowe i wspóĥdziaĥanie
MoĔliwoĈè wspóädziaäania jest kluczowym elementem architektury EJB. Specyfikacja Enterprise
JavaBeans nie tylko obejmuje konkretne wymagania w kwestii obsäugi protokoäu Java RMI-IIOP
(w roli mechanizmu wywoäywania zdalnych metod), ale teĔ definiuje rozwiñzania umoĔli-
wiajñce efektywnñ wspóäpracö w takich obszarach jak przetwarzanie transakcyjne, nazew-
nictwo i bezpieczeþstwo. Specyfikacja EJB wymaga teĔ obsäugi technologii JAX-RPC, która
sama wymaga obsäugi protokoäu SOAP 1.1 oraz jözyka WSDL 1.1, czyli standardów w Ĉwiecie
usäug Web Services.
IIOP
Specyfikacja Enterprise JavaBeans nakäada na producentów serwerów EJB obowiñzek im-
plementowania standardu Java RMI, który z kolei korzysta z protokoäu CORBA 2.3.1 IIOP.
Twórcy specyfikacji zdecydowali siö na zdefiniowanie tego wymagania z myĈlñ o zapewnie-
niu moĔliwoĈci wspóäpracy serwerów aplikacji Javy EE i — tym samym — umoĔliwieniu
komponentom Javy EE (w tym komponentom EJB, aplikacjom, serwletom oraz stronom JSP)
pracujñcym na jednym serwerze Javy EE uzyskiwania dostöpu do komponentom EJB dziaäa-
jñcym na innym serwerze Javy EE. Specyfikacja Java RMI-IIOP definiuje standardy w takich
obszarach jak transfer parametrów, zwracanie wartoĈci, generowanie wyjñtków oraz odwzo-
rowywanie interfejsów i obiektów wartoĈci w jözyku CORBA IDL.
Producenci kontenerów EJB mogñ oczywiĈcie implementowaè obsäugö innych protokoäów
niĔ Java RMI-IIOP, jednak semantyka konstruowanych interfejsów RMI musi pasowaè do ty-
pów obsäugiwanych przez protokóä RMI-IIOP. Zdecydowano siö na to ograniczenie gäównie
po to, by zapewniè spójnoĈè perspektywy klienta EJB niezaleĔnie od stosowanego protokoäu
zdalnych wywoäaþ.