r12-05, Programowanie, ! Java, Java Server Programming


W niniejszym rozdziale:

Rozdział 12.

Serwlety korporacyjne i J2EE

Niniejszy rozdział opisuje serwlety korporacyjne. Termin korporacyjny (enterprise) jest w obecnych czasach mocno związany z Javą, co jednak oznacza? Według starszego wydania słownika „American Heritage Dictionary” słowo enterprise posiada trzy znaczenia:

  1. Podejmowanie działań, zwłaszcza o dużej skali lub ryzyku

  2. Biznes

  3. Gotowość na ryzyko, inicjatywa

Jest to zaskakująco bliska definicja tego, co próbują powiedzieć ludzie mówiący o korporacyjnej Javie i korporacyjnych serwletach. Można połączyć tradycyjne definicje w celu utworzenia definicji nowoczesnej:

  1. Gotowość do obsługi działań biznesowych o dużej skali

Innymi słowy, serwlety korporacyjne to serwlety zaprojektowane do obsługi zorientowanych biznesowo witryn WWW o dużej skali — witryny o wysokim obciążeniu i niezawodności wiążą się z dodatkowymi wymaganiami na temat skalowalności, rozkładu ładunku, obsługi błędów i integracji z innymi technologiami Java 2, Enterprise Edition (J2EE).

Odkąd serwlety zaczęły być coraz bardziej popularne i profesjonalne, a także kontenery serwletów stały się bardziej niezawodne i wszechstronne, coraz większa liczba witryn biznesowych tworzona jest przy pomocy serwletów. Tworzenie serwletów dla takich witryn różni się od tworzenia ich dla witryn tradycyjnych, i w tym rozdziale omówione zostaną specjalne wymagania i możliwości serwletów korporacyjnych.

Dystrybucja ładunku

W przypadku witryn o wysokiej wydajności i/lub niezawodności, często korzystna jest dystrybucja zawartości i przetwarzania witryny pomiędzy większą ilością serwerów wspierających. Dystrybucja ta pozwala kilku serwerom na współdzielenie ładunku, co zwiększa ilość równoczesnych żądań, które mogą zostać obsłużone, oraz pozwala na przetrwanie i działanie witryny nawet wtedy, gdy zawiedzie jeden konkretny składnik.

Dystrybucja nie jest polecana dla każdej witryny. Tworzenie i utrzymanie witryny dystrybuowanej może być w znaczący sposób trudniejsze niż wykonanie tych samych czynności w przypadku witryny samodzielne, oraz bardziej kosztowne w kwestii sprzętu dzielącego ładunek i/lub wymagań programów. Dystrybucja nie przynosi również znaczącej poprawy wydajności, jeżeli serwer nie znajduje się pod maksymalnym obciążeniem. Po wystąpieniu problemu z wydajnością, często najłatwiej jest „rzucić sprzęt na problem” poprzez instalację pojedynczego wysokowydajnego komputera, a nie podzielić ładunek pomiędzy dwoma komputerami o niewystarczającej wydajności.

Istnieje jednak wiele witryn, które wymagają skalowalności poza osiągami dowolnego pojedynczego komputera i poziomu niezawodności niemożliwego do uzyskania na pojedynczym komputerze. W witrynach tych należy zastosować dystrybucję.

Jak być dystrybuowalnym

Wymagania programistyczne dla serwletu dystrybuowalnego są dużo bardziej restrykcyjne niż wymagania odnoszące się do innych serwletów. Serwlet dystrybuowalny musi zostać napisany według konkretnych zasad tak, aby różne egzemplarze serwletu mogły być wykonywane na wielu serwerach wspierających. Każdy programista, który przyjmuje, że istnieje tylko jedna kopia serwletu, jeden kontekst serwletu, jedna wirtualna maszyna Javy i jeden system plików, może sprawić sobie poważne problemy.

Aby zrozumieć, jak serwlety mogą być dystrybuowane, proszę spojrzeć na technologię Enterprise JavaBeans (EJB), model elementów po stronie serwera stworzony w celu implementacji dystrybuowanych obiektów biznesowych, który jest sercem J2EE. EJB jest zaprojektowany od początku jako zbiór obiektów dystrybuowalnych. ELB implementuje logikę biznesową i pozwala kontenerowi (zwykle serwerowi), na którym pracuje, na uruchamianie usług zarządzających takich, jak transakcje, trwałość, współbieżność i bezpieczeństwo. EJB może być dystrybuowany pomiędzy większą ilością komputerów wspierających i może być przenoszony pomiędzy komputerami przy pomocy kontenera. Aby wykorzystywać ten model dystrybucji, EJB musi spełniać ścisły zestaw zasad opartych na --> specyfikacji, mówiący, co może on robić, a czego nie[Author:PG] .

Serwlety nie posiadają takiego opartego na specyfikacji zestawu zasad. Wynika to z ich pochodzenia jako frontowych elementów po stronie serwera, wykorzystywanych do komunikacji z klientem i wywoływania dystrybuowanych EJB, podczas, gdy same serwlety nie są przeznaczone do dystrybucji. Jednak w przypadku witryn o dużym obciążeniu lub witryn, które wymagają wysokiej niezawodności, również serwlety muszą być dystrybuowane. Przypuszcza się, że przyszłe wersje Servlet API będą zawierać ściślejszą definicję implementacji dystrybuowalnych kontenerów serwletów.

Poniżej podano utworzone przez autorów niniejszej książki skrótowe zasady tworzenia serwletów, które mają być umieszczane w środowisku dystrybuowalnym:

Aplikacja WWW, której elementy spełniają powyższe zasady może zostać oznaczona jako dystrybuowalna, a to oznaczenie pozwala serwerowi na uruchomienie jej na kilku serwerach wspierających. Znak dystrybuowalności jest umieszczany w deskryptorze web.xml jako pusty znacznik <distribuable/> umieszczony pomiędzy opisem aplikacji i jej parametrami kontekstu:

<web-app>

<description>

Wszystkie serwlety i strony JSP są gotowe do dystrybucji

</description>

<distribuable/>

<context-param>

<!--...-->

</context-param>

</web-app>

Aplikacje z definicji nie są dystrybuowalne w celu zapewnienia niedoświadczonym programistom serwletów możliwości tworzenia ich bez potrzeby martwienia się o dodatkowe zasady związane z dystrybucją. Zaznaczenie aplikacji jako dystrybuowalnej niekoniecznie oznacza, że aplikacja zostanie podzielona pomiędzy kilkoma różnymi komputerami. Wskazuje to jedynie, że aplikacja ma możliwość bycia dystrybuowaną. Należy myśleć o tym jako o wystawionym przez programistę świadectwie aplikacji.

Serwery nie wymuszają większości podanych powyżej zasad dystrybucji aplikacji. Na przykład, serwlet może wykorzystywać zmienne egzemplarza i statyczne, a także przechowywać obiekty w swoim ServletContext oraz uzyskiwać bezpośredni dostęp do plików przy pomocy pakietu java.io. Od programisty zależy zabezpieczenie tych własności przed nadużyciem. Jedynym działaniem, jakie może podjąć serwer jest wywołanie wyjątku IllegalArgumentException, jeżeli obiekt dowiązany do HttpSession nie jest implementacją java.io.Serializable (a nawet to działanie jest opcjonalne, ponieważ, jak zostanie to opisano później, serwer kompatybilny z J2EE musi pozwalać na przechowywanie w sesji dodatkowych typów obiektów).

Wiele stylów dystrybucji

Dystrybucja serwletów (często nazywana klastrowaniem) jest opcjonalną własnością kontenera serwletów, a kontenery serwletów obsługujące klastrowanie mogą wykonywać je na kilka różnych sposobów. Istnieją cztery standardowe architektury, wymienione poniżej, od najprostszej do najbardziej zaawansowanej.

  1. Brak klastrowania. Wszystkie serwlety wykonywane są wewnątrz jednej wirtualnej maszyny Javy, a znacznik <distributable/> jest właściwie ignorowany. Projekt jest prosty, jednak działa poprawnie w przypadku standardowych witryn. W ten sposób działa samodzielny serwer Tomcat.

  2. Obsługa klastrowania, brak sesji wędrujących i unikania błędów. Serwlety w aplikacji WWW zaznaczone jako <distributable/> mogą być wykonywane na kilku komputerach. Żądania niezwiązane z sesjami są dystrybuowane losowo (z zachowaniem równomiernego obciążenia). Żądania sesji są „lepkie” i przywiązane do konkretnego serwera wspierającego, na którym rozpoczęły działanie. Dane sesji nie przemieszczają się pomiędzy komputerami, co posiada zaletę taką, że sesje mogą przechowywać nie przenoszone dane (nie-Serializable) oraz wadę taką, że sesje nie mogą być przenoszone do niewykorzystywanych serwerów, a serwer może załamać się z powodu uszkodzonej sesji. Architektura ta wykorzystywana jest przez Apache/JServ i Apache/Tomcat. Sesje są przywiązane do konkretnego komputera poprzez mechanizm, w którym łącznik mod_jserv/mod_jk będący częścią Apache'a wykorzystuje część identyfikatora sesji w celu wskazania, który wspierający JServ lub Tomcat jest właścicielem sesji. Wykorzystanych może być również kilka egzemplarzy Apache'a, obsługujących sprzęt lub oprogramowanie rozkładające obciążenie.

  3. Obsługa klastrowania i sesji wędrujących, brak unikania błędów. Architektura ta pracuje podobnie jak poprzednia, poza tym, że sesje mogą przenosić się z jednego serwera do drugiego w celu lepszego rozłożenia obciążenia. Aby uniknąć kwestii współbieżności, każda wędrówka sesji posiada gwarancję wystąpienia pomiędzy żądaniami klienta. Specyfikacja serwletów mówi, że „wewnątrz aplikacji oznaczonej jako dystrybuowalna wszystkie żądanie będące częścią sesji mogą być obsługiwane jedynie przez pojedynczą maszynę wirtualną w jednym czasie”. Wszystkie obiekty umieszczone w sesji, które mają być przenoszone muszą wykorzystywać java.io.Serializable lub mieć możliwość przenoszenia w pewien inny sposób.

  4. Obsługa klastrowania, sesji wędrujących i unikania błędów. Serwer wykorzystujący tę architekturę posiada dodatkową możliwość powielania zawartości sesji tak, że załamanie pojedynczego elementu niekoniecznie niszczy sesje klienta. Wyzwaniem tej architektury jest koordynacja wydajnego przepływu informacji. Architekturę tę wykorzystuje większość wysokowydajnych serwerów.

Szczegóły implementacji klastrowania różnią się między serwerami i są miejscem rywalizacji poszczególnych producentów serwerów. Proszę spojrzeć do dokumentacji własnego serwera w celu uzyskania szczegółów na temat obsługiwanego poziomu klastrowania. Inną przydatną własnością jest trwałość sesji, czyli zapisywanie w tle informacji sesji na dysk lub do bazy danych, co pozwala informacjom na przetrwanie załamań i ponownych uruchomień serwera.

Integracja z J2EE

W poprzednich częściach książki serwlety były wykorzystywane jako samodzielna technologia utworzona na standardowej podstawie Javy. Serwlety posiadają także inne życie, w którym działają jako integralna część czegoś, co nazywane jest Java 2, Enterprise Edition, w skrócie J2EE. J2EE 1.2 zbiera razem kilka interfejsów pracujących po stronie serwera, w tym Servlet API 2.2, JSP 1.1, EJB, JavaMail, Java Messaging Service (JMS), Java Transactions (JTA), CORBA, JDBC, Java API for XML Parsing (JAXP) i Java Naming and Directory Interface (JNDI). J2EE integruje te elementy w coś więcej niż prostą sumę części poprzez zdefiniowanie sposobu współpracy tych technologii, ich wykorzystywania siebie nawzajem oraz dostarczania zaświadczeń, że konkretne serwery aplikacji są zgodne z J2EE, co oznacza, że obsługują wszystkie potrzebne usługi, a także mechanizmy ich integracji.

Podział pracy w J2EE

J2EE rozbija tworzenie aplikacji korporacyjnych na sześć różnych ról. Oczywiście pojedyncza osoba może pełnić więcej niż jedną rolę, albo też kilka osób może pracować wspólnie nad zadaną rolą.

Podział pracy pomiędzy dostawcą elementów, monterem i wdrożeniowcem ma wpływ na zachowanie programisty serwletów w roli dostawcy zawartości. Zwłaszcza należy zaprojektować kod tak, aby uczynić zewnętrzne zależności jasnymi dla montera, a poza tym powinno się wykorzystać mechanizmy pozwalające wdrożeniowcowi na dostosowanie się do tych zależności bez konieczności modyfikacji plików otrzymanych od montera. Oznacza to, że żaden wdrożeniowiec nie edytuje pliku web.xml! Dlaczego nie? Ponieważ aplikacje J2EE są wmontowane w pliki archiwa Enterprise Archive (.ear), w których plik web.xml aplikacji WWW jest jedyną częścią, której nie można edytować.

Brzmi to o wiele trudniej, niż tak naprawdę wygląda. J2EE dostarcza standardowego mechanizmu w celu osiągnięcia tego wyłączenia przy pomocy JNDI i kilku specjalnych znaczników w deskryptorze web.xml. JNDI to mechanizm wyszukiwania obiektów, sposób na związanie ich z konkretnymi ścieżkami i późniejszego odnalezienia przy pomocy danych ścieżek. Można myśleć o tym mechanizmie jak o rejestrze RMI, poza tym, że jest on bardziej ogólny poprzez obsługę dostępu do wielu usług, włączając w to LDAP i NIS (a nawet, właściwie, rejestr RMI!). Monter deklaruje zewnętrzne zależności w web.xml przy pomocy specjalnych znaczników, wdrożeniowiec dostosowuje aplikacje do tych zależności przy pomocy właściwych serwerowi narzędzi, a podczas uruchomienia kod Javy wykorzystuje interfejs JNDI w celu uzyskania dostępu do zasobów zewnętrznych — umieszczonych tam przez serwer zgodny z J2EE. Wszystkie cele zostają wypełnione — kod Javy pozostaje przenośny pomiędzy serwerami zgodnymi z J2EE, a wdrożeniowiec może dostosować się do zależności zewnętrznych bez konieczności modyfikowania plików otrzymanych od montera. W tym miejscu pozostawiono nawet wystarczającą elastyczność, która pozwala producentom serwerów na rywalizację w implementacji standardu.

Pozycje środowiskowe

Parametry inicjacji kontekstu są użyteczne dla serwletów, ale w modelu J2EE istnieje z nimi problem— każda zmiana wartości parametru wymaga modyfikacji pliku web.xml. Zamiast wartości parametrów, które mogą zmienić się w trakcie wdrażania lepiej jest zastosować pozycje środowiskowe, wskazywane przez znaczniki <env-entry>. Znacznik <env-entry> może zawierać znaczniki <description> (opis), <env-entry-name> (nazwa), <env-entry-value> (wartość) i <env-entry-type> (typ). Poniższy <env-entry> określa, czy aplikacja powinna umożliwiać wysyłanie kodu PIN przy pomocy poczty elektronicznej:

<env-entry>

<description>Wysyłanie kodu PIN pocztą</description>

<env-entry-name>pocztaPIN</env-entry-name>

<env-entry-value>false</env-entry-value>

<env-entry-type>java.lang.Boolean</env-entry-type> <!--PNK-->

</env-entry>

Znacznik <description> wyjaśnia wdrożeniowcowi cel tej pozycji. Jest on opcjonalny, lecz warto go umieszczać. <env-entry-name> jest wykorzystywany przez kod Javy jako część wyszukiwania JNDI. <env-entry-value> definiuje domyślną wartość przekazywaną wdrożeniowcowi. On także jest opcjonalny, lecz wart umieszczenia. <env-entry-type> definiuje domyślną pełną nazwę klasy (PNK) pozycji. Typ może być jednym z następujących — String, Byte, Short, Integer, Long, Boolean, Double lub Float (wszystkie z ich pełną kwalifikacją java.lang). Typ pomaga wdrożeniowcowi w zorientowaniu się, czego spodziewa się serwer. Powyższe znaczniki mogą wydawać się znajome osobom, którym nieobcy jest deskryptor EJB, posiadają one identyczne nazwy i semantykę.

Kod Javy może odczytać wartości <env-entry> przy pomocy JNDI:

Context poczKontekst = new InitialContext();

Boolean pocztaPIN = (Boolean) poczKontekst.lookup("java:comp/env/pocztaPIN");

Wszystkie pozycje umieszczane są przez serwer w kontekście java:comp/env. Osoby nie znające JNDI mogą o nim myśleć jako o bazie URL-a lub katalogu w systemie plików. Kontekst java:comp/env ma własności tylko do odczytu i jest unikatowy dla aplikacji WWW, tak więc jeżeli dwie różne aplikacje WWW zdefiniują taką samą pozycję środowiskową, pozycje te nie kolidują. Skrót nazwy kontekstu oznacza component environment (środowisko elementów).

Przykład 12.1 przedstawia serwlet wyświetlający wszystkie jego pozycje środowiskowe, wykorzystując interfejs JNDI do przeglądania kontekstu java:comp/env.

Przykład 12.1.

Przeglądanie kontekstu java:comp/env

import java.io.*;

import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

import javax.naming.*;

public class PrzeglPozSrod extends HttpServlet {

public void doGet(HttpServletRequest zad, HttpServletResponse odp)

throws ServletException, IOException {

odp.setContentType("text/plain");

PrintWriter wyj = odp.getWriter();

try {

Context poczKontekst = new InitialContext();

NamingEnumeration enum = poczKontekst.listBindings("java:comp/env");

// Wykorzystywane są metody JDK 1.2; można to zrobić, ponieważ J2EE wymaga JDK 1.2

while (enum.hasMore()) {

Binding wiazanie = (Binding) enum.next();

wyj.println("Nazwa: " + wiazanie.getName());

wyj.println("Typ: " + wiazanie.getClassName());

wyj.println("Wartość: " + wiazanie.getObject());

wyj.println();

}

}

catch (NamingException w) {

w.printStackTrace(wyj);

}

}

}

Przyjmując poprzednią pozycję web.xml, serwlet wygenerowałby:

Nazwa: pocztaPIN

Typ: java.lang.Boolean

Wartość: false

Proszę pamiętać, że serwer, który nie obsługuje J2EE niekoniecznie obsługuje powyższe znaczniki, ani żadne inne opisywane w tym podrozdziale.

Odwołania do elementów EJB

Jeśli obiekt w pozycji środowiskowej to element EJB, należy wykorzystać specjalny znacznik <ejb-ref>. Daje on serwletom możliwość obsługi EJB przy pomocy abstrakcyjnej nazwy. Wdrożeniowiec zapewnia dostępność odpowiedniego elementu w trakcie uruchamiania w oparciu o ograniczenia podane w znaczniku <ejb-ref>. Znacznik ten może zawierać znaczniki <description>, <ejb-ref-name>, <ejb-ref-type>, <home>, <remote> i <ejb-link>. Poniżej przedstawiony jest typowy <ejb-ref>:

<ejb-ref>

<description>Kabiny na statku wycieczkowym</description>

<ejb-ref-name>ejb/KabinaPocz</ejb-ref-name>

<ejb-ref-type>Entity</ejb-ref-type>

<home>com.tytan.kabina.KabinaPocz</home>

<remote>com.tytan.kabina.Kabina</remote>

</ejb-ref>

Powyższe znaczniki posiadają również swoje odpowiedniki w EJB, i właściwie przykład ten jest zapożyczony z książki „Enterprise JavaBeans” autorstwa Richarda Monson-Haefela (O'Reilly). <ejb-ref-name> nadaje nazwę do poszukiwań JNDI. Poleca się (chociaż nie jest to konieczne) umieszczenie nazwy w podkontekście ejb/, co sprawia, że pełna ścieżka do elementu to java:comp/env/ejb/KabinaGlowny. <ejb-ref-type> musi posiadać wartość Entity lub Session (są to typy elementów EJB). Natomiast element <home> określa pełną nazwę klasy interfejsu właściwego EJB, podczas gdy element <remote> określa PNK interfejsu zdalnego EJB.

Serwlet może odczytać odwołanie do elementu Kabina przy pomocy następującego kodu:

InitialContext poczKontekst = new InitialContext();

Object odw = poczKontekst.lookup("java:comp/env/ejb/KabinaPocz");

KabinaPocz pocz = (KabinaPocz) PortableRemoteObject.narrow(odw, KabinaPocz.class);

Jeżeli monter tworzący plik web.xml chce umieścić w odwołaniu EJB konkretny element EJB, informacja ta może zostać przekazana wdrożeniowcowi przy pomocy opcjonalnego elementu <ejb-link>. Element <ejb-link> powinien odwoływać się do <ejb-name> komponentu EJB zarejestrowanego w deskryptorze EJB w tej samej aplikacji J2EE. Wdrożeniowiec posiada możliwość skorzystania z sugestii bądź opuszczenia jej. Poniżej przedstawiona jest uaktualniona pozycja web.xml:

<ejb-ref>

<description>Kabiny na statku wycieczkowym</description>

<ejb-ref-name>ejb/KabinaPocz</ejb-ref-name>

<ejb-ref-type>Entity</ejb-ref-type>

<home>com.tytan.kabina.KabinaPocz</home>

<remote>com.tytan.kabina.Kabina</remote>

<ejb-link>KabinaElement</ejb-link>

</ejb-ref>

Odwołania do zewnętrznych fabryk zasobów

Ostatecznie, w przypadkach, w których pozycja środowiskowa to fabryka zasobów, wykorzystuje się znacznik <resource-ref>. Fabryka to obiekt, który na żądanie tworzy inne obiekty. Fabryka zasobów tworzy obiekty zasobów, takie jak połączenia z bazami danych lub kolejki wiadomości.

Znacznik <resource-ref> może zawierać znaczniki <description>, <res-ref-name>, <res-type> i <res-auth>. Poniżej przedstawiony jest typowy znacznik <resource-ref>:

<resource-ref>

<description>Podstawowa baza danych</description>

<res-ref-name>jdbc/podstawBD</res-ref-name>

<res-type>javax.sql.DataSource</res-type>

<res-auth>CONTAINER</res-auth>

</resource-ref>

W tym przypadku <description> również służy jak wsparcie dla wdrożeniowca i jest opcjonalny, ale polecany. <res-ref-name> zawiera nazwę do poszukiwań JNDI. Poleca się, lecz nie jest to wymagane, aby fabryki zasobów były umieszczane w podkontekście, który określa typ zasobów:

Element <res-type> określa PNK fabryki zasobów (a nie utworzonego zasobu). Typy fabryk na powyższej liście to typy standardowe. Serwer posiada możliwość obsługi dodatkowych typów; nie mogą zostać zastosowane fabryki użytkownika. Specyfikacja nadchodzącej wersji 1.3 J2EE zawiera mechanizm „łącznika” służący do rozszerzania tego modelu o fabryki zdefiniowane przez użytkownika.

<res-auth> służy do przekazania serwerowi informacji, kto jest odpowiedzialny za uwierzytelnianie. Znacznik ten może posiadać dwie wartości — CONTAINER lub SERVLET. Jeżeli jego wartość wynosi CONTAINER, wtedy kontener serwletów (serwer J2EE) obsługuje uwierzytelnianie przed dowiązaniem fabryki do JDNI, przy pomocy danych dostarczonych przez wdrożeniowca. Jeżeli wynosi SERVLET, uwierzytelnienie musi zostać przeprowadzone programowo przez serwlet. Poniższy kod przedstawia ten mechanizm:

InitialContext poczKontekst = new InitialContext();

DataSource zrodlo = (DataSource) poczKontekst.lookup("java:comp/env/jdbc/podstawBD");

// Jeżeli "CONTAINER"

Connection pol1 = zrodlo.getConnection();

// Jeżeli "SERVLET"

Connection pol2 = zrodlo.getConnection("user", "password");

Powyższe znaczniki również posiadają swoje odpowiedniki w deskryptorze EJB. Jedyną różnicą jest fakt, że w EJB dwie możliwe wartości <res-auth> to Container i Application (proszę zauważyć niewyjaśnioną różnicę w wielkości liter).

Dystrybucja serwletów w środowisku J2EE

Ostatnia różnica pomiędzy serwletami w środowisku samodzielnym i serwletami w środowisku J2EE związana jest z niewielką zmianą w zasadach dystrybucji sesji. Podczas gdy standardowy serwer WWW musi obsługiwać w sesji jedynie obiekty java.io.Serializable aplikacji dystrybuowalnej, serwer zgodny z J2EE, który obsługuje dystrybuowalny kontener serwletów musi również obsługiwać kilka dodatkowych typów obiektów:

Wszystkie powyższe interfejsy to interfejsy, które nie wykorzystują Serializable. W celu przeniesienia tych obiektów kontener może wykorzystać swój własny mechanizm, który może (ale nie musi) być oparty na serializacji. Dodatkowe typy klas mogą być obsługiwane w zależności od serwera, ale powyższe to jedyne typy, których obsługa jest gwarantowana.

Większa ilość informacji na temat Enterprise JavaBeans dostępna jest pod adresem http://java.sun.com/products/ejb i w książce „Enterprise JavaBeans” autorstwa Richarda Monson-Haefela (O'Reilly).

Większość ludzi wymawia J2EE jako J-2-E-E, ale specjaliści z firmy Sun mówią po prostu „jah-too-ee”

Specyfikacja Servlet API 2.2 głosi, że „element ejb-ref-type zawiera przewidywany typ klasy Javy dla EJB stanowiącego cel odwołania”. Jest to potwierdzony błąd. Właściwy cel jest taki, jak wymieniony powyżej.

2 Część I Podstawy obsługi systemu WhizBang (Nagłówek strony)

2 C:\0-praca\Java Servlet - programowanie. Wyd. 2\r12-t.doc

Do red prow: w przypisie autor powołuje się na jakąś książkę, może jakąś naszą?



Wyszukiwarka

Podobne podstrony:
r20-05, Programowanie, ! Java, Java Server Programming
O Autorach-05, Programowanie, ! Java, Java Server Programming
r05-05, Programowanie, ! Java, Java Server Programming
r07-05, Programowanie, ! Java, Java Server Programming
r03-05, Programowanie, ! Java, Java Server Programming
rE-05, Programowanie, ! Java, Java Server Programming
r19-05, Programowanie, ! Java, Java Server Programming
r17-05, Programowanie, ! Java, Java Server Programming
r11-05, Programowanie, ! Java, Java Server Programming
rD-05, Programowanie, ! Java, Java Server Programming
rF-05, Programowanie, ! Java, Java Server Programming
r04-05, Programowanie, ! Java, Java Server Programming
r13-05, Programowanie, ! Java, Java Server Programming
r01-05, Programowanie, ! Java, Java Server Programming
r10-05, Programowanie, ! Java, Java Server Programming
r02-05, Programowanie, ! Java, Java Server Programming
rB-05, Programowanie, ! Java, Java Server Programming
05 Programowanie

więcej podobnych podstron