Skip to main content

Posts

Showing posts from 2008

Wzorzec Command - elastyczny protokół sieciowy

Postanowiłem przedstawić, moim zdaniem, jeden z najciekawszych wzorców projektowych: Command. Idea tego wzorca opiera się na zamknięciu logiki w posiadających jednolite interfejsy obiektach i możliwości dowolnego mapowania tych akcji do zdarzeń. Ale zamiast opowiadać i pokazywać diagramy UML - nie do końca trywialny przykład. Wyobraźmy sobie protokół sieciowy typu klient-serwer oparty o komunikaty w następującym formacie: [nazwa_komunikatu] [opcjonalne_parametry] Klient wysyła do serwera komunikat w powyższym formacie a w odpowiedzi dostaje dowolny tekst. Problem w tym, że chcemy by protokół był bardzo elastyczny pod kątem obsługiwanych komunikatów. W szczególności dodanie nowego typu komunikatu (rozpoznawanego po nazwie) obsługiwanego przez serwer i związanej z nim logiki biznesowej powinno być możliwie łatwe. Oczywiście wpisanie typów komunikatów do kodu i korzystanie z instrukcji typu if czy switch nie wchodzi w grę. Ale po kolei... Zacznijmy od prostego kodu serwera: class

Tomcat z JavaRebel i aplikacja Struts2

Ponieważ od kilku dni mogę się pochwalić brązowym pasem na JavaBlackBelt, postanowiłem wypróbować narzędzie JavaRebel, do którego to licencję otrzymałem za darmo . Padło na aplikację w Struts2 na Tomkacie 6.0, zacznijmy od niej: mvn archetype:create -DgroupId=strutstest -DartifactId=strutstest -DarchetypeGroupId=org.apache.struts -DarchetypeArtifactId=struts2-archetype-starter -DarchetypeVersion=2.0.11.2-SNAPSHOT -DremoteRepositories=http://people.apache.org/repo/m2-snapshot-repository I aplikacja gotowa. Teraz czas przygotować Tomcata, na szczęście ogranicza się to do dodania dwóch magicznych linijek do skryptu catalina.bat: set JAVA_OPTS=-noverify -javaagent:C:/apps/JavaRebel/1.2.1/javarebel.jar %JAVA_OPTS% set JAVA_OPTS=-Drebel.dirs=D:/temp/strutstest/target/classes %JAVA_OPTS% Pierwsza komenda wskazuje ścieżkę do JARa JavaRebel i jest dość oczywista. Druga wskazuje katalog, w którym maven (i - jak się za chwilę przekonamy - Eclipse) umieszcza skompilowane pliki .class. Innym

Strumienie w Javie - cheat sheet

Jednym z częściej spotykanych przeze mnie problemów w Javie jest ogarnięcie różnych rodzajów strumieni i metod reprezentacji danych. Jak bowiem poradzić sobie np. z biblioteką, która wymaga danych w jedynie słusznej tablicy charów a my właśnie dostaliśmy strumień wejściowy z socketu? [*] Z uwagi na mnogość klas I/O w Javie takich dylematów powstaje niezliczona ilość. Wyjść jest kilka, z reguły przechodzimy przez kila warstw obiektów (w końcu biblioteka I/O w Javie realizuje wzorzec chain of responsiility ), w najgorszym wypadku w pętli przepisując dane z jednego miejsca w drugie. Nawet jeśli znalazłem już konkretne rozwiązanie, i tak z reguły pozostaje niesmak i przeświadczenie, że może dałoby się to zrobić krócej/lepiej/szybciej, niepotrzebne skreślić. W tym celu przygotowałem ściągawkę , jeśli choć jedna osoba ją sobie wydrukuje i powiesi na biurkiem, będzie to mój sukces :-). Czekam również na poprawki i propozycje, wciąż wiele ścieżek nie jest uzupełnionych. [*] - z rysunku dowiadu

Relacja z Java Developers' Day 2008

Dzięki uprzejmości mojej firmy miałem w tym roku niewątpliwą przyjemność uczestniczyć w Java Developers' Day 2008 w Krakowie. Krótko o prelekcjach, których miałem możliwość wysłuchać: Na początek keynote w wykonaniu Teda Newarda . To, co miało być pogadanką o wszystkim i o niczym gościa z USA było pasjonującą podróżą po językach programowania od lat 60 do niedalekiej przyszłości. Ogromne pokłady humoru i kilka mniej lub bardziej kontrowersyjnych opinii o relacjach między światem akademickim i komercyjnym. Na koniec usłyszeliśmy tezę, że " God doesn't think in objects " z żartobliwym autoripostą " He thinks in Ruby " :-). Mnóstwo ciekawostek i humoru rodem z za oceanu. Słuchało się tego z przyjemnością.* Potem było JAIN SLEE ustami Jana Pieczykolana . To mógł być dobry i ciekawy wykład, ale... Niestety mam wrażenie, że gdyby prelegent nie skupił się tak mocno na promocji własnej firmy, starczyłoby mu czasu na ciekawą demonstrację. A tak - było po prostu nu

java.lang.reflect.Proxy czyli prawie AOP za prawie darmo

Począwszy od Javy 1.3 programistom (głównie frameworków) została udostępniona niezwykle użyteczna klasa Proxy . Zasadniczo klasa ta pomaga w implementacji wzorca projektowego o tej samej nazwie, jednak skupię się na przykładzie użycia samej klasy, reszta będzie już oczywista. Proxy jest swoistą warstwą pośredniczącą między obiektem docelowym a światem zewnętrznym. Wywołanie każdej metody obiektu docelowego "przechodzi" przez proxy, które ma pełen zestaw możliwości wpływania na to wywołanie (podejrzenie i zmiana parametrów, logowanie, a nawet całkowite zaniechanie wywołania właściwej metody). Jeśli znacie metody z grupy java.util.Collections.synchronized*() , to koncepcyjnie zwracają one właśnie takie proxy, które opakowuje wszystkie wywołania metod docelowej kolekcji. Rolą proxy jest w tym przykładzie zapewnienie synchronizacji na poziomie każdej metody i oczywiście wywołanie właściwej metody. Podobnie możemy sobie wyobrazić proxy zabezpieczające kolekcję przed modyfikacją, k

Log4j bez konfiguracji

Często piszę króciutkie programy z samym mainem tylko po to, aby sprawdzić działania nieznanej funkcji API czy właśnie zaimplementowanego algorytmu. Ot taki proof-of-concept jeszcze przed napisaniem testów jednostkowych (wiem, wiem, testy piszemy najpierw, ale...) Aby zachować pewne standardy staram się nawet w takim testowym kodzie używać Log4j do pary z commons-logging zamiast klasycznego System.out.println() . Nie tylko lepiej wygląda, ale też Log4j zapewnia pewne dodatkowe informacje. Niestety kod: import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; class Main {   private static final Log log = LogFactory.getLog(Main.class);   public static void main(String[] args) {   log.info("Example message");   } }   spowoduje wyświetlenie co najwyżej znanego skądinąd błędu: log4j:WARN No appenders could be found for logger (Main). log4j:WARN Please initialize the log4j system properly. W takich sytuacjach z reguły kopiowałem p

Generyczne testy z adnotacją Parameters w JUnit 4

Wydawałoby się, że JUnit jest na tyle prostą biblioteką, iż nic nie jest w stanie nas w niej zaskoczyć. A jednak, odkryłem niedawno ciekawą adnotację @Parameters pozwalającą na generowanie testów z dostarczonych danych. Przykład wiele rozjaśni: @RunWith(Parameterized.class) public class ParamsTest { private int a; private int b; private int expected; @Parameters public static Collection data() { return Arrays.asList(new Object[][] { { 1, 1, 2 }, { 1, 2, 3 }, { 4, 6, 9 }, { -2, 2, 0 } }); } public ParamsTest(int a, int b, int expected) { this.a = a; this.b = b; this.expected = expected; } @Test public void sum() { assertEquals(expected, a + b); } } Należy zwrócić uwagę na dwie rzeczy: brak konstruktora bezargumentowego; normalnie JUnit nie byłby w stanie uruchomić jakiegokolwiek testu z tekiej klasy metoda data() zwraca kolekcję tablic. JUnit automatycznie dla k