Zarządzalne ziarna (MBeans) w JVM i serwerze aplikacji JBoss

Serwer aplikacji JBoss udostępnia poprzez szereg ziaren możliwość zarówno sprawdzenia stanu w jakich one się znajdują, jak i wykonywanie różnych operacji na nich. Dostać się do nich można poprzez konsolę JMX.

Poniżej znajduje się lista tych bardziej interesujących (ale w żadnym wypadku nie jest to lista ani pełna, ani wyczerpująca):

  • java.lang:type=OperatingSystem
    Pozwala na wyświetlenie informacji o systemie operacyjnym na którym jest uruchomiony serwer aplikacji. Można tu odczytać takie informacje o ilości otwartych plików, ilości i zużyciu pamięci, architekturze serwera, obciążeniu serwera, ilości procesorów.
  • java.lang:type=ClassLoading
    Informacje o załadowanych klasach w JVM: ilość załadowanych klas, ilość usuniętych klas, całkowita ilość załadowanych klas. Można także włączyć opcję Verbose, która spowoduje, że w momencie ładowania jakiejś klasy zostanie wypisany na standardowe wyjście komunikat o tym. Może to być przydatne podczas debugowania aplikacja, w przypadku problemów z ładowaniem klas.
  • java.lang:type=Compilation
    Informacje o kompilatorze oraz czasie jaki został poświęcony na kompilację kodu do bytecodu.
  • java.lang:type=GarbageCollector,name=nazwa kolektora
    Informacje o odśmiecaczu, takie jak ile razy był uruchomiony, ile czasu potrzebował do działania, nazwy przestrzeni na zmienne używane przez grabage collector.
  • java.lang:type=Memory
    Informacje o aktualnym stanie pamięci w JVM. Istnieje możliwość włączenia trybu Verbose, dzieki któremu można się dowiedzieć o pamięci zwalnianej przez odśmiecacz. Można także wymusić wywołanie garbage collectora poprzez metodę gc(). Funkcjonalnie odpowiada to wywołaniu metody System.gc().
  • java.lang:type=Runtime
    Szereg informacji o maszynie wirtualnej Javy, takie jak: ścieżka klas, właściwości JVM, argumenty wejściowe dla JVM, nazwa producenta JVM, wersja JVM, lista bibliotek dla JVM, czas działania.
  • java.lang:type=Threading
    Interfejs ten pozwala na zapoznanie i zarządzanie wątkami uruchomionymi w ramach maszyny wirtualnej Javy. Przy jego pomocy można uzyskać zarówno informacje o ilości uruchomionych wątków, ich numerach ID oraz informacje o poszczególnych wątkach.
    Dostępna jest także metoda, pozwalające na sprawdzenie czy nie ma wątków zablokowanych (findDeadlockedThreads).
  • jboss:type=Service,name=SystemProperties
    Pozwala na wyświetlenie informacji systemowych. Posiada metodę showAll, która wyświetla wszystkie właściwości w kolejności alfabetycznej. Można się dowiedzieć co kryje się pod systemowymi właściwościami używanymi przez serwer aplikacji, takimi jak: jboss.server.data.dir czy jboss.server.name.
  • jboss:service=JNDIView
    Pozwala na wyświetlenie obiektów zarejestrowanych w JNDI. Posiada dwie metody list oraz listXML, które pozwalają wyświetlić informacje o poszczególnych obiektach i ich nazwach zarejestrowanych w JNDI. Przydatne w przypadku problemów z obiektami pozyskiwanymi z katalogu, takimi jak brak nie rozpoznana nazwa, problem z rzutowaniem klas.
  • jboss.system:type=Log4jService,service=Logging
    Pozwala na konfigurację logowania serwera JBoss. Logowanie odbywa się przy użyciu biblioteki Log4j a to ziarno pozwala na bezpośrednią modyfikację jej konfiguracji: zmianę poziomu logowania, zmianę sposobu logowania poszczególnych komponentów, konfigurację czy przechwytywać komunikaty wypisywane na standardowe wyjście, plik konfiguracyjny i okres jego sprawdzania.
  • jboss.system:service=ThreadPool
    Pozwala na sprawdzanie oraz zarządzanie rozmiarem puli wątków. Można sprawdzić ilość połączeń oczekujących na obsługę (parametr QueueSize) i w razie potrzeby zwiększyć ilość działających wątków (parametr MaximumPoolSize).
  • jboss.system:type=Server
    Podstawowe informacje o serwerze aplikacji JBoss: wersja, data zbudowania, data uruchomienia. Pozwala także na wyłączenie serwera, uruchomienie odśmiecacza.
  • jboss.system:type=ServerConfig
    Lokalizacja szeregu katalogów używanych przez JBossa, takich jak katalog domowy, tymczasowy i inne. Pozwala także na konfigurację sposobu opuszczania JVM w momencie kończenia pracy przez serwer aplikacji (czy JVM także ma kończyć swoją pracę w momencie zamykania JBossa).
  • jboss.system:type=ServerInfo
    Wyświetlenie informacji o JVM oraz systemie operacyjnym. Posiada oprócz tego metody pozwalające na wyświetlenie informacji o zużyciu poszczególnych obszarów pamięci GC (listMemoryPools), wyświetlenie informacji o wybranym pakiecie (displayPackageInfo), zużyciu procesora przez poszczególne wątki (listThreadCpuUtilization), zrzut informacji o wątkach (listThreadDump).

Źródła

Tags: , , , ,

Zmiana wewnętrznej bazy danych JBossa (HSQLDB) na MySql

W domyślnej instalacji JBoss używa wewnętrznie bazy danych HSQLDB. Jest to baza danych napisana w 100% w Javie. Całkiem dobrze sprawdza się w prostych zastosowaniach jako baza danych wbudowana, ale bywają z nią problemy jeżeli nasze wymagania rosną.

W przypadku serwera JBoss baza ta posiada kilka zalet:

  • bardzo dobrze sprawdza się w środowisku deweloperskim
  • jest skonfigurowana do działania od razu po instalacji serwera, nie wymaga żadnej konfiguracji
  • prosta w użyciu

Ale jest także szereg wad, które uniemożliwiają jej używanie w systemie produkcyjnym, charakteryzującym się potrzebą dużej wydajności i niezawodności:

  • brak izolacji transakcji
  • problemy z wyciskania wątków czy socketów
  • występowanie błędów w przypadku błędnego zamknięcia bazy danych
  • problemy ze stabilnością w przepadku dużego obciążenia serwerów

Zaleca się, aby w systemach produkcyjnych zmienić bazę danych HSQLDB na inną, bardziej stabilną i o większych możliwościach. Zmiana konfiguracji po stronie serwera JBoss nie jest bardzo skomplikowana, należy wykonać kilka kroków. Poniższy opis odnosi się do bazy danych MySql, ale nie powinno sprawić wielkich trudności przerobienie go na dowolną inna bazę danych.

Krok 1: Instalacja serowników bazy danych

Pierwszym krokiem powinna być instalacja odpowiednich sterowników bazy danych. Należy skopiować je do katalogu $JBOSS_HOME/common/lib. W tym katalogu znajdują się biblioteki dostępne we wszystkich profilach, więc będzie można w każdym z nich ich używać.

W przypadku bazy danych MySql odpowiednie sterowniki można pobrać ze strony producenta: Download Connector/J. Pobrane archiwum należy rozkompresować i skopiować znajdujący się tam plik mysql-connector-java-*.jar do katalogu $JBOSS_HOME/common/lib lub też katalogu [lib] danego profilu.

Krok 2: Konfiguracja bazy danych

Kolejnym krokiem jest utworzenie bazy danych oraz odpowiedniego użytkownika. Należy połączyć się z bazą danych i wydać odpowiednie polecenia:

$ mysql -u root

Teraz wystarczy utworzyć bazę danych i odpowiedniego użytkownika:

1
2
CREATE DATABASE jboss_server;
GRANT ALL PRIVILEGES ON jboss_server.* TO jboss_user@'localhost' IDENTIFIED BY 'haslo';

Oczywiście nazwa bazy danych, użytkownika oraz hasło należy sobie odpowiednio dobrać. Jeżeli baza danych nie znajduje się na tym samym serwerze co serwer aplikacji, to także należy odpowiednio zmodyfikować ten wpis (czyli zmienić localhost na odpowiednią nazwę hosta).

Krok 3: Konfiguracja domyślnego źródła danych

Domyślna baza danych nazywa się DefaultDS i jej konfiguracja (dla wbudowanej bazy danych) znajduje się w pliku deploy/hsqldb-ds.xml dla danej konfiguracji serwera JBoss. Aby używać innej bazy danych, należy:

  • usunąć plik hsqldb-ds.xml z katalogu deploy (najlepiej przenieść do go innej katalogu)
  • utworzyć nową definicję domyślnej bazy danych specyficzną dla wybranego serwera bazodanowego

Warto pamiętać, że przykładowe konfiguracje źródeł danych dla różnych baz danych można znaleźć w katalogu $JBOSS_HOME/docs/examples/jca.

Czyli należy usunąć plik hsqldb-ds.xml a następnie utworzyć plik default-ds.xml dla bazy danych MySql:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>DefaultDS</jndi-name>
    <connection-url>jdbc:mysql://localhost:3306/jboss_server</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>jboss_user</user-name>
    <password>haslo</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>
  </local-tx-datasource>
</datasources>

Krok 4: Konfiguracja JMS

W domyślnej konfiguracji JMS korzysta z wbudowanej bazy danych. Zakłada, że tą bazą danych jest HSQLDB. Konfiguracja dostępu znajduje się w pliku deploy/messaging/hsqldb-persistence-service.xml. Należy zamiast tego pliku przygotować konfigurację specyficzną dla bazy danych. Przykładowe konfiguracje można znaleźć w katalogu $JBOSS_HOME/docs/examples/jms.

W podanej konfiguracji wystarczy skopiować plik $JBOSS_HOME/docs/examples/jms/mysql-persistence-service.xml do katalogu deploy/messaging/ oraz usunąć plik hsqldb-persistence-service.xml.

Po tych operacjach wystarczy uruchomić ponownie serwer aplikacji JBoss i jeżeli nie wystąpiły żadne błędy, powinniśmy mieć już zdefiniowaną zewnętrzną bazę danych dla serwera.

Źródła

Tags: , , , , ,

Odszukanie plików JAR z brakującymi definicjami klas

Często pojawiającym się problem (i bardzo irytującym przy okazji) podczas uruchamiania aplikacji napisanych w Javie jest brak jakiś klas potrzebnych do uruchomienia aplikacji. Ja się ostatnio spotkałem z takim problemem próbując testować jakąś aplikację, której autorów nikt od dawana nie widział.

Znam dwie metody na sprawdzenia, jak nazywa się plik JAR z daną klasą:

Odszukanie pliku JAR przy użyciu strony internetowej

Przy użyciu wyszukiwarki FindJAR.com można w łatwy sposób sprawdzić, w jakich plikach znajduje się poszukiwana klasa. Wystarczy w polu wyszukiwania wpisać nazwę klasy (niekoniecznie nawet z pełną nazwą pakietu), ewentualnie wybrać dokładną nazwę klasy z prezentowanych odpowiedzi i już widać, w jakich plikach znajduje się dana klasa.

Zrobiłem test dla klasy javax.jws.WebParam, wyniki można zobaczyć tutaj: http://www.findjar.com/class/javax/jws/WebParam.html:

findJAR wyniki dla WebParam

findJAR wyniki dla WebParam

Teraz pozostaje tylko pobrać plik i przynajmniej jedną klasę mamy już głowy ;).

Odszukanie pliku jar przy użyciu aplikacji

Do odszukania potrzebnych plików można także użyć aplikacji [cco]jarSearch[/cci]. W artykule Which jar contains my… można znaleźć dokładny opis możliwości aplikacji (większy niż przedstawiony tutaj) oraz link do źródeł.

Aplikacja przeszukuje podany katalog oraz podkatalogi w celu odnalezienia plików JAR i sprawdza czy znajduje się w nim podana klasa. Jeżeli znajdzie ją, to wyświetla odpowiednią informację.

Po pobraniu pliku zip jarSearchSrc.zip z plikami źródłowymi, należy je skompilować:

$ ant build
Buildfile: build.xml

build:
   [delete] Deleting directory /home/lukasz/install/java/jarSearch/classes
    [mkdir] Created dir: /home/lukasz/install/java/jarSearch/classes
    [javac] Compiling 4 source files to /home/lukasz/install/java/jarSearch/classes

BUILD SUCCESSFUL
Total time: 1 second

Aby użyć jarSearch należy z katalogu z plikiem build.xml wydać komendę:

$ java -cp jarSearch.jar com.isocra.utils.jarSearch.DirectorySearcher /jboss-as/client/ javax.jws.WebParam.class
/jboss-as/client/jbossws-native-jaxws.jar: javax/jws/WebParam.class
1 entries found.
Directory searcher: http://www.isocra.com

Pierwszym parametrem jest katalog z który zawiera pliki jar, drugim natomiast nazwa szukanej klasy. W powyższym przykładzie widać, że został odnaleziony jeden plik, który zawiera poszukiwaną klasę jbossws-native-jaxws.jar

Widać, że efekty działania obu sposobów są trochę inne. Strona findJAR oferuje nam możliwość odnalezienia wybranej klasy i następnie ściągnięcia odpowiedniego pliku. Natomiast aplikacja jarSearch pozwala po prostu sprawdzić w której bibliotece ukrywa się szukana klasa.

Źródła

Tags: , , , , ,

Wyłączenie dźwięków systemowych GTK pod KDE

Pracując głównie w środowisku KDE wyłączyłem wszelkie możliwe dźwięki systemowe, niestety ustawienia te nie były respektowane przez aplikacje korzystające GTK, takie jak Firefox czy Eclipse. Ciągle w nich pobrzmiewały pikania przy przełączaniu się pomiędzy zakładkami, plikami, otwieraniu okien dialogowych.

Rozwiązanie jak się okazuje jest całkiem proste ;). Wystarczy do pliku konfiguracyjnego GTK dodać wpis wyłączający wydawanie dźwięków przez aplikacje. W moim przypadku jest jest to plik ~/.gtkrc-2.0-kde4 (podejrzewam, że w środowisku GTK może mieć nazwę bez końcówki -kde4) oraz w pliku należy wstawić to:

gtk-enable-event-sounds=0

Od tego momentu ani Firefox ani Eclipse nie wydają dźwięków.

Źródła

Tags: , , , , ,

Zarządzanie instalacją aplikacji w JBoss AS

Jeżeli JBoss AS zostanie uruchomiony w domyślnej (default) konfiguracji to jest wstępnie skonfigurowany tak, że automatycznie instaluje wszelkie aplikacje jakie pojawią się w katalogu deploy. Podobnie, jeżeli jakąś aplikacja zostanie usunięta z tego katalogu, to automatycznie zostanie ona także odinstalowana z serwera. Zachowanie takie jest bardzo przydatne w momencie gdy tworzymy lub testujemy aplikację, ale niekoniecznie porządne na systemie produkcyjnym. Automatyczna instalacja aplikacji może się wiązać z takimi problemami jak:

  • ciągle jest uruchomiony specjalny wątek, który sprawdza czy nowa aplikacja nie pojawiła się w katalogu deploy;
  • trzeba pamiętać, że aktualizacja aplikacji wiąże się w w praktyce z usunięciem aplikacji z serwera i jej ponowną instalacją, więc jeżeli z jakiś powodów zaktualizujemy aplikację, nastąpi jej usunięcie, co w konsekwencji może przeszkodzić w pracy użytkownikom korzystającym z aplikacji;
  • przypadkowa (czy też nawet zamierzona) edycja plików deskryptora aplikacji także powoduje jej restart.

Konfiguracja skanowania zmian w katalogu deploy

Za konfigurację mechanizmu skanującego zmiany w katalogu deploy odpowiada klasa HDScanner. Konfiguracja usługi znajduje się w pliku deploy/hdscanner-jboss-beans.xml:

10
11
12
13
14
15
16
17
18
19
<!-- Hotdeployment of applications -->
<bean name="HDScanner" class="org.jboss.system.server.profileservice.hotdeploy.HDScanner">
    <property name="deployer"><inject bean="ProfileServiceDeployer"/></property>
    <property name="profileService"><inject bean="ProfileService"/></property>
    <property name="scanPeriod">5000</property>
    <property name="scanThreadName">HDScanner</property>
<!--
   <property name="scanEnabled">false</property>
-->
</bean>

Interesujące parametry:

  • scanPeriod
    Czas odstępu pomiędzy poszczególnymi skanowaniami wyrażona w milisekundach, domyślna wartość to 5000, czyli 5 sekund.
  • scanThreadName
    Nazwa wątka, który skanuje katalogu, domyślna wartość HDScanner. Można zmienić na inną wartość, jeżeli monitorujemy działające wątki serwera.
  • scanEnabled
    Zmienna określająca, czy skanowanie powinno być włączone (wartość true) czy też nie (wartość false). W domyślnej konfiguracji nie występuje w pliku XML. Próba dodanie jej z wartością true powoduje, że serwer wyrzuca szereg wyjątków:

    23:34:18,727 ERROR [AbstractKernelController] Error installing to Configured: name=HDScanner state=Instantiated
    java.lang.RuntimeException: Error configuring property: scanEnabled for HDScanner
            at org.jboss.kernel.plugins.dependency.ConfigureAction.dispatchSetProperty(ConfigureAction.java:112)
            at org.jboss.kernel.plugins.dependency.ConfigureAction.setAttributes(ConfigureAction.java:85)
    ...

    Prawdopodobnie jest to spowodowane błędem Setting HDScanner’s scanEnabled Attribute to True via XML Results In NPE lub też Setting HDScanner’s scanEnabled Attribute to True via XML Results In NPE

Jak widać, nie da się po prostu włączyć odpowiedniego przełącznika i wyłączyć automatyczną instalację aplikacji. W związku z tym, należy usunąć z katalogu deploy plik hdscanner-jboss-beans.xml[.

Po tym kroku przestanie działać usługa odpowiedzialna za skanowanie katalogu deploy, więc zmiany w nim będą sprawdzane tylko podczas startu serwera aplikacji.

Ręczna instalacja aplikacji

Jeżeli jest wyłączone automatyczne skanowanie katalogu deploy a trzeba zainstalować jakąś aplikację, można użyć polecenia twiddle.sh za pomocą którego można wywołać ziarno MainDeployer, które odpowiada za instalację aplikacji:

  • deploy – instalacja wybranej aplikacji
    twiddle.sh -s localhost -u UŻYTKOWNIK -p HASŁO invoke "jboss.system:service=MainDeployer" deploy "file:/ścieżka/do/pliku/do/instalacji"
  • undeploy – odinstalowanie wybranej aplikacji
    twiddle.sh -s localhost -u UŻYTKOWNIK -p HASŁO invoke "jboss.system:service=MainDeployer" undeploy "file:/ścieżka/do/pliku/do/instalacji"
  • redeploy – przeinstalowanie wybranej aplikacji
    twiddle.sh -s localhost -u UŻYTKOWNIK -p HASŁO invoke "jboss.system:service=MainDeployer" redeploy "file:/ścieżka/do/pliku/do/instalacji"
  • hdscanner-jboss-beans.xml – ponowna instalacja skanowania
    1. Skopiuj plik hdscanner-jboss-beans.xml z powrotem do katalogu deploy.
    2. Wykonaj polecenie:
      twiddle.sh -s localhost -u UŻYTKOWNIK -p HASŁO invoke "jboss.system:service=MainDeployer" redeploy "file:/ścieżka/do/pliku/xml"

Co trzeba jeszcze zapamiętać:

  • serwera aplikacji musi mieć dostęp do wskazanego pliku
  • aplikacja do zainstalowania zostanie zainstalowana bezpośrednio, nie będzie ona kopiowania do katalogu deploy, zostanie ona od razu rozkompresowana do katalogu tmp
  • zainstalowane aplikacje nie będę ponownie uruchamiane po restarcie serwera (chyba że zostaną one umieszczone w katalogu deploy ręcznie.

Lista zainstalowanych aplikacji

Można uzyskać listę zainstalowanych aplikacji, przy pomocy polecenie twiddle:

twiddle.sh invoke jboss.deployment:flavor=URL,type=DeploymentScanner listDeployedURLs | sed -e 's/,/\n/g'

Domyślnie poszczególne ścieżki z aplikacji są oddzielone od siebie znakiem ‚,’, polecenie sed zmienia je na znak nowej linii.

Źródła

Tags: , , , , ,