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 Main {

privat…

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 rozwiązanie…

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 dowiadujemy …

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 nudno.Na szc…

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ą, któr…

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 plik log4j.xml z jakiegokolw…

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 każdego elementu kolekcji zwró…