25 styczeń 2009

UnsatisfiedLinkError na Mac OS X

Na Mac OS X od czasu do czasu nie działa coś zwiazanego z Javą 6. W zasadzie to nie mam pojęcia dlaczego Apple zajmuje się implementacją Javy, a nie Sun jak na pozostałaych systemach. Jakiś czas temu chciałem uruchomić aplikację korzystającą z zewnętrzenej biblioteki. Aplikacja ta umożliwia komunikację z urządzeniami przez port RS232. Mimo różnych kombinacji ciągle program nie widział wymaganej biblioteki:

java.lang.UnsatisfiedLinkError: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/librxtxSerial.jnilib: thrown while loading gnu.io.RXTXCommDriver
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/librxtxSerial.jnilib:
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1822)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1723)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at gnu.io.CommPortIdentifier.(CommPortIdentifier.java:83)
at eu.gruchala.rs232.ListAvailablePorts.(ListAvailablePorts.java:23)
at eu.gruchala.rs232.MainFrame$1.run(MainFrame.java:77)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:461)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:176)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

Okazało się, że problem leży w Javie 6 i Javie 5 64-bitowej. Nie wiem dlaczego, ale te wersje choćby nie wiem co, nie widzą zależnych bibliotek niejawowych. Aby program zadziałał, wystarczy przełączyć system na uruchomianie aplikacji z Javą 5 32-bity lub podłączyć bibliotekę skompilowaną na 64-bity. Powinna nazywać się libXXX.jnilib gdzie XXX to nazwa jaką ładujemy w kodzie programu np.:
System.loadLibrary("XXX");



17 styczeń 2009

Enterprise JavaBeans 3.0: stanowe ziarna sesyjne

Stateful Session Beans (@Stateful) są bardzo podobne do ziaren bezstanowych. Różnią się w zasadzie cyklem życia. Kontener dba o to, aby ziarno stanowe nie zgubiło nigdzie stanu, który przechowuje oraz aby każde kolejne wywołanie metody biznesowej danego bean'a nie zostało wywołane przez klienta, który nie jest związany z tym ziarnem. Dlatego odwrotnie do Stateless session beans, ziarna stanowe są powiązane tylko i wyłącznie z jednym klientem.

Cykl życia jest trochę bogatszy od ziaren bezstanowych. Zawiera to co one oraz dwa dodatkowe stany:

  • @PrePassivate - wywołane przed dezaktywacją bean'a,
  • @PostActivate - wywołane po aktywacji.
Ale czym jest ta "pasywacja"? Nie zawsze jest tak, że ziarno stanowe jest potrzebne, ale nadal przecież musi przechowywać swój stan. W momencie gdy tak się dzieje, kontener dezaktywuje je, przenosi z pamięci aktywnej do tymczasowej (zapisuje na dysku) wykorzystując serializację (dlatego też ziarna stanowe i powiązane z nimi obiekty muszą implementować java.io.Serializable). Proces ten jest nazwany passivation. Po polsku może to być pasywacja lub wymyślona na moje potrzeby dezaktywacja. Gdy ziarno będzie znowu potrzebne, kontener je aktywuje i wywoła również to co jest w metodzie z adnotacją @PostActivate.

W związku z tym zapisywaniem, należy pamiętać o poprawnym wykorzystywaniu tych adnotacji aby kontener zapisywał tymczasowo jak najmniejsze ilości danych. W zasadzie to się tyczy całych ziaren stanowych. Należy z nich korzystać tylko w razie konieczności starając się minimalizować ich obciążenie.

Ziarno kończy swój żywot, gdy już nie jest potrzebne poprzez wywołanie metody oznaczonej @Remove lub time out. Można w niej np. "znullować" (język polski jest super) zmienne stanowe.

15 styczeń 2009

Enterprise JavaBeans 3.0: bezstanowe ziarna sesyjne

No to teraz już wszystko będzie proste ;-) W komentarzu do poprzedniego posta napisałem, że ziarna nazywane są sesyjne ze względu na nazwanie tak czasu wywołania/trwania metody biznesowej. Innym określeniem tego procesu jest konwersacja. Stateless Session Beans (@Stateless) nie przechowują żadnego stanu, dlatego wywołanie danej metody może zakończyć cykl życia bezstanowego ziarna (tak na chama to w stanowych też, ale nie są one po to, żeby być tak na chwilę ;-)). Generalnie rzecz biorąc każde ziarno kiedyś powstaje i kiedyś kończy swój żywot. Albo poprzez time out serwera albo wywołanie metody z adnotacją @Remove (ale to cecha ziaren stanowych).

Stateless session beans są bardzo "wydajne". Załóżmy, że mamy 1000 klientów naszej aplikacji. Mimo tak dużej ilości klientów korzystających z naszego ziarna kontener nie będzie tworzył tak dużej ilości instancji. Dlatego, że:

  • mało prawdopodobne żeby wszyscy naraz korzystali z tego samego
  • ziarenka odwalą swoją robotę i czekają aż będą mogły znowu pomóc, czyli istniejące instancje są przetrzymywane w puli i używane na nowo w razie potrzeby. Jest to pooling.
Występują tutaj dwa cykle życia:
  • @PostConstruct - metoda tak adnotowana zostanie wywoałana po stworzeniu instancji bean'a oraz wstrzyknięciu zależności,
  • @PreDestroy - wywoływany tuż przed zniszczeniem instancji ziarna.
Oprócz wcześniej wspomnianych adnotacji interfejsu biznesowego @Local i @Remote, bezstanowe ziarna posiadają jeszcze jeden dodatkowy - @WebService. Żadne inne ziarno nie może posiadać tak oznaczonego interfejsu z dość prostej przyczyny. Bezstanowe ziarna nie przetrzymują stanu, który musiałby być jakoś przesłany przez HTTP.

07 styczeń 2009

6 spotkanie Szczecin JUG - Błażej Ksycki - GlassFish


Zapraszam na kolejne spotkanie. Tym razem o serwerze aplikacyjnym GlassFish opowie Błażej Ksycki.



Błażej Ksycki jest absolwentem Wydziału Informatyki Politechniki Szczecińskiej. W ciągu jego kariery zawodowej miał styczność z wieloma różnymi technologiami, od programowania gier w telefonach z Symbianem, po webowe aplikacje klasy enterprise. Z samą Javą zawodowo ma styczność od kilku lat.


Temat: "Dlaczego nie GlassFish?"

1) Czym są serwery aplikacji i jaka jest ich rola

2) Wady i zalety GlassFish'a

3) GlassFish FAQ

4) Porównanie z innymi serwerami aplikacji

5) Instalacja na Windowsie i Linuksie




Do wygrania jak zwykle licencja na jeden z wymienionych produktów
firmy JetBrains:
a. IntelliJ IDEA Personal License
b. ReSharper Personal License
c. TeamCity Build Agent
d. Ruby Mine


Miejsce: WI ZUT (PS), sala 128
Godz. 18:00
Data: 15.01.2009
Rejestracja: JUGEVENTS


Zapraszam w imieniu swoim i Błażeja.

05 styczeń 2009

Enterprise JavaBeans 3.0: Ziarna sesyjne

Mała dygresja. Naukę EJB 3.0 rozpocząłem od przeczytania Simplified API dostępnego na stronie http://java.sun.com/products/ejb/docs.html. Przyznam, mimo że rzeczy fajne, to spać mi się chciało nie raz. Teraz przerzuciłem się na EJB in Action wydawnictwa Manning. Czyta się dużo przyjemniej, wszystko jest fajnie objaśnione. To co będziecie mogli znaleźć u mnie to w dużej mierze sedno informacji zawartych w tej książce jak i innych znalezionych na sieci, czy zdobytych własnym doświadczeniem. Na tę chwilę - naprawdę warto kupić tę książkę. Recenzję napiszę po przeczytaniu całości.

Aby dobrze zrozumieć czym są stanowe i bezstanowe ziarenka, warto nauczyć się czym w ogóle są session beans i co nam oferują...
  • klienci - wywołać wspomniane ziarna może aplikacja desktopowa w Swingu, aplikacja webowa (np. JSP, JSF, servlet), czy nawet aplikacja .Net'owa korzystając z Web Service'u.
  • współbieżność i bezpieczeństwo wątków - tworząc aplikacje serwerowe liczymy się z tym, że będą one pracowały nawet dla tysięcy użytkowników. Ale my przecież mamy wiele komponentów, ziarna stanowe, bezstanowe, interceptory. Kontener automagicznie zadba o to, aby tylko i wyłącznie jeden wątek miał dostęp do danego beana. W przypadku gdy wystąpią dwa jednoczesne wywołania kontener rzuci wyjątek javax.ejb.ConcurrentAccessException (co może się zmieni w Java EE 6 bo nie wszystkim podobają się te ograniczenia).
  • zdalne wywoływanie - ziarna sesyjne mogą być wywoływane zdalnie w dwojaki sposób, poprzez RMI (Remote Method Invocation) lub web service'y. Co ważne, nie trzeba przy tym nic konfigurować oprócz 1 (słownie: jednej ;-)) linii adnotacji.
  • transakcje i bezpieczeństwo - czyli Java Persistence API (do omówienia innym razem) i (dzięki oficjalnemu standardowi) wszystkie bajery dostępne wraz z Java EE.
  • programowanie aspektowe i "usługi czasowe" - interceptory pozwalają na wywoływanie określonych zadań w momencie wywołania beanów, czy konkretnej metody danego ziarna. Jednocześnie nie łączą się bezpośrednio z nimi co pozwala na redukcję powtarzającego się kodu. Możliwe jest także wiązanie ziaren ze schedulerami (jak to będzie po polsku?).
Każde ziarno sesyjne składa się z dwóch nierozłącznych rzeczy:
  • interfejs biznesowy - musi być przynajmniej jeden, może być lokalny lub zdalny, klienci nie mogą odwoływać się do konkretnych implementacji. Swoją drogą wartą tę regułę zastosować do każdego aspektu programowania. Pozwala to na modyfikację implementacji bez obawy, że wyrządzimy komuś krzywdę choćby brakiem wstecznej kompatybilności.
  • implementacja - konkretny Plain Old Java Object (POJO), czyli zwykła klasa Java z dodanymi adnotacjami. Adnotacje EJB nie nie mają znaczenia dla JVM, są one istotne dopiero w momencie uruchomiania EJB w/na kontenerze. Bean nigdy nie może być klasą abstrakcyjną.
Parę zasad:
  • Ziarno musi posiadać bezparametrowy publiczny konstruktor. Zadeklarowany jawnie lub nie.
  • Ziarno może rozszerzać inne ziarna, ale co z adnotacjami? Są ignorowane oprócz adnotacji dotyczących cyklu życia, wstrzykiwania zależności czy zasobów.
  • Metody biznesowe nie mogą zaczynać się od ejb. Muszą być publiczne, a nie mogą być finalne i statyczne. Metody oznaczone jako zdalne czyli @Remote - ich argumenty i zwracany typ musi implementować java.io.Serializable (ponieważ obiekty przesyłane zamieniane są w strumienie bajtów, dlatego warto uważać, aby nie były to duże obiekty).
Interfejs biznesowy to po prostu Plain Old Java Interface (POJI) z dołożoną adnotacją. Dane ziarno może posiadać wiele interfejsów, ale chociaż jeden musi być interfejsem biznesowym.

PS. Czy uważacie, że spolszczanie nazw komponentów EJB ma sens?

03 styczeń 2009

Enterprise JavaBeans 3.0: Wprowadzenie

Po co nam biznesowe ziarna javowe? Ano po to by było nam lżej. Każdy z nas prędzej czy później zmierzy się z aplikacją, która będzie musiała działać dla wielu użytkowników/zapytań itd., być dobrze zabezpieczona, obsługiwać różnego rodzaju błędy, wyjątki, sytuacje, przypadki, być łatwa w utrzymaniu, rozwoju itd. itp. Można by tak wymieniać i wymieniać. Z pomocą przychodzi nam właśnie EJB. Jest to standard, rozwijany przez społeczność Javy, który ma na celu pomóc developować aplikacje m.in. działające na serwerach aplikacji: Tomcat, GlassFish, JBoss itd., i zapewnić nam "łatwy" rozwój tej aplikacji, jej przenośność pomiędzy różnymi serwerami oraz zapobiec wymyślaniu kolejnego koła. Kołem tym jest zapewnienie bezpieczeństwa, transakcyjności, skalowalności, obsługi błędów... Tak, jest to kolejny framework, ale wart uwagi ze względu na oficjalny standard oraz możliwość interakcji z innymi framework'ami np. Springiem.


Na Enterprise JavaBeans 3.0 składają się:
  • Session beans - ziarna sesyjne
  • Message-driven beans - ziarna sterowane komunikatami
  • Interceptors - interceptory dla ziaren sesyjnych
i tak trochę osobno:
  • Entities - encje
Od wersji EJB 3.0 encje nie są już komponentami biznesowymi. Zostały wydzielone do Java Persistence API (JPA) i można ich używać także w aplikacjach desktopowych np. do komunikacji z lokalną bazą danych.

Głównym komponentem EJB jest klasa komponentu biznesowego. Aby klasa mogła nim być musi spełnić parę warunków:
  • musi być określony typ ziarna - w pliku XML (deskryptorze wdrożenia) lub (i to jest super ;-) ) klasa musi zostać zadnotowana jako utrzymująca stan @Stateful lub bezstanowa @Stateless.
  • musi posiadać interfejs biznesowy oznaczony jako lokalny @Local (domyślnie) lub zdalny @Remote. Jeśli klasa implementuje jeden interfejs nie musimy podawać żadnej adnotacji czy definiować tego w pliku xml. Jeśli jest ich więcej, każdy musi być oznaczony jako interfejs biznesowy, oczywiście interfejs nie może być jednocześnie zdalny i lokalny. Następujące interfejsy są wykluczone z określania czy dany interfejs jest biznesowy: java.io.Serializable oraz java.io.Externalizable.
  • interfejs biznesowy nie może rozszerzać javax.ejb.EJBObject i javax.ejb.EJBLocalObject.
Oczywiście interfejsy mogą rzucać wyjątki, ale nie powinien to być java.rmi.RemoteException, ponieważ ten wyjątek już jest opakowany przez EJBException, a zajmie się tym kontener, czyli serwer aplikacji.

Kolejną bardzo ważną i fajną rzeczą jest Dependency Injection, czyli wstrzykiwanie zależności. W EJB 2.1 programiści byli zmuszeniu korzystać z JNDI (Java Naming and Directory Interface), jest to usługa, która pozwala przeszukiwać klasy, zasoby itp. Musieli oni przy tym pisać dużo zbędnego kodu i właśnie w ziarnach sesyjnych odwoływać się do konkretnych ziaren, zasobów. W EJB 3.0 kierunek został odwrócony. Wystarczy, że podacie nad danym interfejsem adnotację @EJB, a to kontener zajmie się znalezieniem odpowiedniej implementacji i wstrzyknie ją w beana. Podobnie jest z innymi zasobami, ale tam używana jest adnotacja @Resource.

W każdym przypadku zamiast adnotacji, można użyć konfiguracji w pliku xml. Jeśli obawiacie się, że to nie jest takie super, bo zapytacie: Co jeśli wprowadzę w adnotacjach konfigurację projektu, po czym przeniosę ją na inny serwer aplikacyjny z innymi ustawieniami? Można wtedy użyć deployment descriptor'a, czyli pliku ejb-jar.xml i tam zminić konfigurację :-)

Skoro tyle razy pojawił się wyraz biznesowy to musi to być fajne i na czasie ;-)