Posts Tagged JBoss

Logowanie przychodzących połączeń HTTP w serwerze JBoss AS i Apache Tomcat

Standardowo (przynajmniej w przypadku JBossa) nie są śledzone przychodzące połączenia HTTP. Może to wprowadzać pewną konsternację :), na szczęście łatwo to zmienić.

Odpowiednie modyfikacje należy wprowadzić w pliku server.xml, który w przypadku JBossa (5.0) znajduje się w katalogu deploy/jbossweb.sar odpowiedniej konfiguracji, z którą serwer jest uruchamiany.

Logowanie odbywa się przez klasę AccessLogValve uruchomianą jako valve (hmm, kranik z angielska, ale nie mam pojęcia jak to będzie po polsku). Należy więc odszukać definicję z tą klasą i ją po prostu odkomentować. Wygląda ona następująco:

80
81
82
83
<Valve className="org.apache.catalina.valves.AccessLogValve"
    prefix="localhost_access_log." suffix=".log"
    pattern="common" directory="${jboss.server.log.dir}"
    resolveHosts="false" />

Konstrukcję tę można umieścić w dowolnym kontenerze (Context, Host, Engine) i będą wtedy zapisywane wszystkie połączenia przechodzące przez dany komponent.

Dopuszczalne parametry konfiguracyjne:

  • className
    Nazwa klasy, która ma odpowiadać za obsługę logowania. Do wyboru są dwie wartości:

    • org.apache.catalina.valves.AccessLogValve – bardziej ogólna, umożliwia zdefiniowanie zakresu logowanych informacji
    • org.apache.catalina.valves.FastCommonAccessLogValve – klasa przeznaczona do wykorzystania na systemach produkcyjnych, umożliwia jedynie na logowanie informacji w formacie common lub combined
  • prefix
    Ciąg znaków dodawany na początku nazwy pliku z logiem. Domyślną wartością jest access_log.
  • suffix
    Ciąg znaków dodawany na końcu nazwy pliku z logami.
  • pattern
    Ciąg znaków zawierający informacje o tym, co powinno zostać zapisane w pliku z logami. Może to być definicja używający specjalnych znaczników lub też słowa common lub combined oznaczające jeden ze standardów logowanych informacji. Dokładną specyfikację można znaleźć w dokumentacji Tomcata.
  • directory
    Ścieżka dostępu do katalogu w którym powinny być zapisywane pliki z logami.
  • resolveHosts
    Jeżeli zostanie ustawiona na true to adresy IP zostaną zamienione na nazwy domenowe (będzie to negatywnie wpływało na wydajność, ponieważ będą potrzebne dodatkowe zapytania do serwera DNS). Jeżeli parametr przyjmie wartość false, zostaną użyte adresy IP.
  • rotatable
    Parametr określa, czy plik z logami ma być rotowany. Domyślnie przyjmuje wartość true. Jeżeli zostanie ustawiony na false, plik z logiem nigdy nie będzie rotowany oraz zawartość pola fileDateFormat zostanie zignorowana.
  • condition
    Włączenie logowania warunkowego. Jeżeli parametr zostanie ustawiony na jakąś wartość, to informacja o połączeniu zostanie zalogowań tylko wtedy, gdy ServletRequest.getAttribute() będzie równe null. Jeżeli wartością parametru będzie loguj, to połączenie zostanie zalogowane tylko wtedy, gdy będzie spełniony ten warunek: ServletRequest.getAttribute("loguj") == null.
  • fileDateFormat
    Pozwala na określenie formatu daty w nazwie pliku z logiem. Jednocześnie decyduje o tym, jak często plik ten będzie rotowany. Aby włączyć rotowanie co godzinę, można ustawić wartość parametru tak: yyyy-MM-dd.HH.

Źródła

Tags: , , , , ,

Zarządzanie transakcjami przez serwer aplikacji

W środowiskach zarządzanych (czyli np w serwerze aplikacyjnym JBoss AS) to te systemu mogą zarządzać transakcjami, czyli rozpoczynać, kończyć je w odpowiednim momencie, zwalniając z tego obowiązku programistę. W aplikacji można zdefiniować, jak dany fragment kodu ma wpływać na transakcje. Jeżeli sposób zachowanie nie zostanie zdefiniowany przez metodę, to kontener rozpoczyna transakcję zanim rozpocznie się wykonywanie metody, i kończy ją tuż przed końcem jej wykonywania. Nie są dozwolone zagnieżdżone transakcje, każda metoda może zostać skojarzona z jedną transakcją.

Definicja rodzaju transakcji

Rodzaje transakcji można zdefiniować przy użyciu adnotacji TransactionAttribute oraz TransactionAttributeType.

Adnotacja TransactionAttribute może występować zarówno na poziomie deklaracji klasy jak i deklaracji metody. Jeżeli zostanie podana przy deklaracji klasy, oznacza to że dany poziom transakcji ma zostać użyty we wszystkich metodach danej klasy, w przypadku deklaracji na poziomie metody odnosi się tylko do niej. W przypadku gdy występuje w jednym jak i drugim miejscu, pod uwagę brana jest wartość występująca przy deklaracji metody.

Poniżej przykład deklarowania rodzajów transakcji, na poziomie klasy i metod:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class UserManager {
   
    @TransactionAttribute(TransactionAttributeType.SUPPORTS)
    public String getUserName() {
        return null;
    }
   
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void setUserName(String name) {
       
    }
}

Typy transakcji

Za pomocą adnotacji TransactionAttributeType można zdefiniować rodzaj transakcji, jaka ma obowiązywać w metodach. Występują następujące typy transakcji:

  • MANDATORY
    Konieczność wykonania metody w ramach istniejącej już transakcji. Jeżeli dla danego klienta istnieje już działająca transakcji, dana metoda zostanie w jej ramach wykonana. Jeżeli natomiast taka transakcji nie istnieje, to zostanie wyrzucony wyjątek TransactionRequiredException. Należy użyć tego atrybutu używać wtedy, gdy dana metoda musi zostać wykonana w ramach transakcji klienta.
  • REQUIRED
    Jeżeli klient działa w ramach transakcji i zostanie wywołana metoda oznaczona tym typem, to zostanie ona wykonana w ramach tej transakcji. Jeżeli natomiast klient nie działa w ramach transakcji, to zostanie rozpoczęta nowa, zanim metoda zostanie uruchomiona. Jest to także domyślne zachowanie, jeżeli nie zostanie ustawiony typ transakcji.
  • REQUIRES_NEW
    Jeżeli klient nie działa w ramach transakcji, to po prostu jest rozpoczynana nowa przed uruchomieniem metody. Natomiast jeżeli jest istnieje już działająca transakcja, to podejmowane są następujące kroki:

    1. Zawieszenie aktualnie działającej transakcji.
    2. Rozpoczęcie nowej transakcji do wykonania wybranej metody.
    3. Wywołanie i wykonanie metody.
    4. Po zakończeniu działania metody ponowne uruchomienie wcześniej zawieszonej transakcji.

    Typu tego należy używać w sytuacji, gdy istnieje potrzeba wykonywania danej metody zawsze w nowej transakcji.

  • SUPPORTS
    Jeżeli klient działa w ramach transakcji i wywoła daną metodę, to zostanie ona wykonana w ramach tej transakcji. Jeżeli natomiast transakcja nie istnieje, to nie zostanie ona także rozpoczęta przed wykonaniem wybranej metody.
  • NOT_SUPPORTED
    Jeżeli klient działa w ramach transakcji, to zostanie ona zatrzymana na czas wywołania wybranej metody, a po jej wykonaniu ponownie przywrócona. Jeżeli nie ma takiej transakcji, metoda zostanie po prostu wykonana, bez rozpoczynania nowej.

    Należy używać tego typu wtedy, gdy wybrana metoda nie potrzebuje transakcji do działania, a zależy nam na większej wydajności jej wykonywania (transakcje mają negatywny wpływ na szybkość wykonywania metod).

  • NEVER
    Jeżeli klient działa w ramach transakcji i wywoła metodą oznaczoną tym typem, zostanie wyrzucony wyjątek RemoteException. Natomiast jeżeli transakcja nie istnieje, to metoda zostanie wykonana bez rozpoczynania nowej transakcji.

Mała tabela, która podsumowuje powyższe:

Zachowanie kontenera w zależności od typu i stanu transakcji
Nazwa atrybutu Transakcja istnieje Brak transakcji
MANDATORY używa istniejącej wyrzuca wyjątek
REQUIRED używa istniejącej rozpoczyna nową
REQUIRES_NEW zawiesza istniejącą, rozpoczyna nową rozpoczyna nową
SUPPORTS używa istniejącej działa bez
NOT_SUPPORTED zawiesza istniejącą działa bez
NEVER wyrzuca wyjątek działa bez

Źródła

Tags: , , , , ,

Zmiana domyślnej implementacji JSF w serwerz JBoss AS

Domyślną implementacją JSF w serwerze aplikacji JBoss AS w wersji 4.2 oraz 5 jest biblioteka o nazwie Mojarra. Wcześniej była używana biblioteka Apache MyFaces. Ponieważ istnieje wiele różnych implementacji JSF, może zajść potrzeba użycia własnej wersji. Aby jej używać, trzeba zrobić dwie rzeczy:

  • dodać biblioteki do pakietu z aplikacją
  • poinformować serwer JBoss, aby używał dostarczonej biblioteki, a nie dostarczanych z serwerem, czyli zmodyfikować plik web.xml:
    <context-param>
    <param-name>org.jboss.jbossfaces.WAR_BUNDLES_JSF_IMPL</param-name>
    <param-value>true</param-value>
    </context-param>

Źródła

Tags: , , ,

Cykl życia strony JSF

W najprostszej formie cykl życia strony JSF nie rożni się od wywołania zwykłej strony JSP: klient wysyła żądanie pobrania wybranej strony a serwer generuje stroną poprzez wywołanie odpowiedniego serwletu. Jednakże model działania stron JSF jest bardziej skomplikowany, wymaga on aby komponenty były odpowiednio sprawdzane, pozwala na przechwycenie odpowiednich zdarzeń, pozwala na przesyłanie danych i tak dalej.

Poniższy rysunek (z dokumentacji The JEE 5 Tutorial, The Life Cycle of a JavaServer Faces Page) prezentuje poszczególne elementy cyklu życia aplikacji:

Standardowy cykl życia strony JSF

Standardowy cykl życia strony JSF

Powyższy diagram zawiera opis dwóch typów zapytań: żądanie początkowe oraz żądanie wyświetlenie ponowne. Żądanie początkowe występuje wtedy, gdy użytkownik wyświetla daną stronę po raz pierwszy, natomiast z wyświetleniem ponownym do czynienia mamy w momencie np. przesłania formularza, który był wcześniej wczytany w fazie pierwszej. Jeżeli następuje żądanie początkowe, to wykonywane są tylko kroki związane z przywróceniem widoku oraz wygenerowaniem odpowiedzi, ponieważ nie ma żadnych danych do przetworzenia. Natomiast z drugim przypadku cykl życia obejmuje wszystkie fazy.

Jeżeli żądanie wyświetlania strony JSF pochodzi z kliknięci ana linka o zwykle jest początkowe żądanie wyświetlenia strony. W takim przypadku zostaje utworzony nowy widok i zapisany w instancji klasy FacesConfig. Aplikacja następnie pobiera obiekty niezbędne do wyświetlenia widoku i wywołuje metodę FacesContext.renderResponse, która powoduje natychmiastowe utworzenie strony z pominięcie Render Response Phase. Operacja ta jest widoczna na diagramie pod nazwą Render Response.

Istnieje czasem potrzeba przekierowanie strony w jakiejś inne miejsce (dostęp do jakiegoś pliku, usługi) lub też strona nie zawiera żadnych komponentów JSF. W takiej sytuacji należy pominąć krok Render Response Phase poprzez wywołanie metody FacesContext.responseComplete. Sytuacja taka znajduje się na diagramie oznaczona nazwą Response Complete.

Restore View Phase

Pierwszą fazą w cyklu życia strony JSF jest Restoe View Phase. Jest ona wywoływana po tym, jak serwer zostanie poproszony o wyświetlenie strony po wybraniu np. jakieś linka. Podczas tej fazy biblioteka JSF tworzy widok, wiąże odpowiednie uchwyty zdarzeń oraz walidatory z odpowiednimi komponentami na widoku, oraz zapisu tak przygotowaną stronę w swojej pamięci podręcznej.

Jeżeli jest to żądanie początkowe zostaje zvudowany pusty widok i następuje przejście do kroku Render Response Phase, gdzie pusty widok jest wypełniany odpowiednimi komponentami znajdującymi się na stronie (czyli następuje utworzenie strony HTML)

Jeżeli natomiast mamy do czynienie z żądaniem ponownym, to widok odpowiadający danej stronie już istnieje w pamięci JSF. Następuje wtedy jego przywrócenie przy użyciu informacji o stanie zapisanych po stronie klienta lub serwera i przejście do następnego kroku.

Apply Request Values Phase

Po odczytaniu struktury komponentu z pamięci podręcznej JSF w pamięci jest już utworzone drzewo komponentów i teraz każdy z nich odczytuje nowe parametry czy też wartości z parametrów przekazanych w zapytaniu o stronie. Odczytana wartość zostaje lokalnie zapisane w danym komponencie. Jeżeli z jakiś powodów nie uda się poprawnie odczytać wartości, zostanie utworzony komunikat o błędzie skojarzony z odpowiednim komunikatem i wysłany do kolejki komunikatów FacesContext. Zostanie on potem wyświetlony już w trakcie tworzenia strony HTML, łącznie z innymi komunikatami które zostały czy też zostaną w kolejnych fazach utworzone.

Process Validations Phase

Podczas tego kroku następuje sprawdzenie poprawności danych zapisanych w poszczególnych komponentach. Sprawdzeniu zostają poddane odpowiednie atrybuty komponentów i są one testowane pod kątek zdefiniowanych reguł oraz ograniczeń.

Jeżeli wystąpi błąd podczas testów, zostaje wygenerowany komunikat błędu i dodany do kolejki komunikatów w FacesContext. W takim przypadku następuje także przejście do fazy odpowiedzialnej za utworzenie strony HTML (Render Response Phase), gdzie nastąpi wyświetlenie wszystkich komunikatów o błędach.

Trzy uwagi:

  • jeżeli jakakolwiek metoda wywoływana podczas tej fazy wywoła metodę FacesConext.renderResponse nastąpi przejście do kroku tworzenia strony HTML (Render Response Phase)
  • jeżeli aplikacje chce przekierować zapytań do innego zasobu (strony) lub też na stronie nie ma komponentów JSF, może wywołać metodę FacesContext.responseComplete
  • jeżeli jakieś zdarzenie zostaną zakolejkowane to JSF prześle je do nasłuchujących obiektów

Update Model Values Phase

Po sprawdzeniu, że dane są poprawne, JSP może zająć się ustawianiem odpowiednich wartości w obiektach znajdujących sie po stronie serwera. Zaktualizowane zostaną tyle te wartości, które zostały przesłane do aktualizacji w zapytaniu o stronę. Jeżeli wystąpią błędy podczas przypisywania wartości, to JSF przejdzie do kroku tworzenia strony HTML (Render Response Phase).

Trzy uwagi (jak wyżej):

  • jeżeli jakakolwiek metoda wywoływana podczas tej fazy wywoła metodę FacesConext.renderResponse nastąpi przejście do kroku tworzenia strony HTML (Render Response Phase)
  • jeżeli aplikacje chce przekierować zapytań do innego zasobu (strony) lub też na stronie nie ma komponentów JSF, może wywołać metodę FacesContext.responseComplete
  • jeżeli jakieś zdarzenie zostaną zakolejkowane to JSF prześle je do nasłuchujących obiektów

Invoke Application Phase

Podczas tego kroku JSF przetwarza wszelkiego rodzaju zdarzenia mające miejsce na poziomie aplikacji, takie jak wysłanie formularza czy też linkowania do innej strony.

Trzy uwagi (jak wyżej):

  • jeżeli jakakolwiek metoda wywoływana podczas tej fazy wywoła metodę FacesConext.renderResponse nastąpi przejście do kroku tworzenia strony HTML (Render Response Phase)
  • jeżeli aplikacje chce przekierować zapytań do innego zasobu (strony) lub też na stronie nie ma komponentów JSF, może wywołać metodę FacesContext.responseComplete
  • jeżeli jakieś zdarzenie zostaną zakolejkowane to JSF prześle je do nasłuchujących obiektów

Render Response Phase

Podczas tej fazy JSF generuje stronę przy użyciu JSP (jeżeli używamy JSP do generowania stron). W przypadku żądania początkowego komponenty znajdujące się na stronie zostaną dodane do drzewa komponentów jak tylko kontener JSP wykona stronę. Każdy komponent będzie samodzielnie tworzył odpowiedni kod HTML w monecie wywołania przez JSP.

W przypadku, gdy pojawią się jakieś błędy z poprzednich faz, zostanie wyświetlona oryginalna strona wraz z odpowiednimi komunikatami o błędach.

Po poprawnym utworzeniu strony jej stan zosanie zapisany, tak aby dało się go ponownie wykorzystać w razie potrzeby.

Źródła

Tags: , , , , ,

Brak uzupełniania kodu podczas edycji strony JSF w Eclipse

Czasami zdarza się, że brakuje autouzpełniania kodu (np. beanów) podczas edycji stron JSF (lub XHTML) w Eclipsie. Podczas otwierania takiej strony pojawia się następujące ostrzeżenie:

Brak właściwości JSF

Brak właściwości JSF

Informuje ono, że nie zostały włączone właściwości związane z JSF. Od razu także kieruje na stronę JBosstoolsVisualEditorFAQ, gdzie można znaleźć opis problemu i jego rozwiązanie. Niestety, w moim przypadku rozwiązanie nie zadziałało do końca ;), więc poniżej szczegółowa recepta co zrobić, aby włączyć obsługę autouzupełniania kodu na stronach JSF

Pierwszym krokiem jest taka konfiguracja projektu, aby Eclipse wiedział, że używamy JSF. Należy zaznaczyć projekt w widoku Project Explorer, wywoałć menu przy użyciu prawego klawisza myszy, wybrać pozycję Configure, i na końcu Add JSF Capabilities.

Dodanie możliwości związane z JSF

Dodanie możliwości związane z JSF

Zostanie uruchomiony kreator, w którym należy zdefiniować podstawowe informacje o projekcie.

W pierwszym kroku należy podać nazwę projektu, oraz wskazać lokalizację pliku web.xml danego projektu. W moim przypadku obie wartości były zdefiniowane poprawnie.

Kreator dodania właściwości JSF, strona 1

Kreator dodania właściwości JSF, strona 1

W drugim kroku należy zdefiniować trochę więcej parametrów:

  • Web Root – ścieżka dostępu do zasobów WWW
  • Source Folder – ścieżka dostępu do plików źródłowych
  • Classes Folder – ścieżka dostępu do skompilowanych plików źródłowych
  • Lib Folder
  • Servlet Version
  • Context Path
  • Runtime – serwer, na którym będzie publikowana aplikacja

W moim przypadku musiałem skonfigurować dwa parametry ręcznie:

  • Classes Folder – został błędnie wykryty przez kreator, trzeba było zmienić ścieżka do katalogu build/classes
  • Runtime – podać właściwy serwer, który ma być używany do uruchamiania aplikacji
Kreator dodania właściwości JSF, strona 2

Kreator dodania właściwości JSF, strona 2

Po tych modyfikacjach powinno już działać autouzpełnianie beanów zarówno na strona JSF jak i XHTML.

Tags: , , , , , ,