SCJP zdany!

Po 10 dniach ciężkich przygotowań do certyfikatu SCJP udało się zdać egzamin na 86%. Ulżyło mi, gdyż poziom szczegółowości pytań był bardzo duży, a pytania skonstruowane tak, że łatwo było się pomylić lub zabrnąć w ślepy kąt.

Jeżeli Oracle nic nie wymyśli i nie zrezygnuje z certyfikacji w takiej formie, jaka jest teraz, to niedługo zaczynam naukę do SCWCD (Sun Certified Web Component Developer). Biorąc pod uwagę fakt, że będąc na studiach mam dość dużo czasu, trzeba to jakoś wykorzystać.

Sun Certified Java Programmer

Walidacja identyczności haseł – Hibernate Validator, Spring Framework

Natknąłem się na problem walidacji identyczności haseł w formularzu rejestracji użytkownika.
Korzystam ze Spring Frameworka, a do walidacji wykorzystuję bibliotekę Hibernate Validator w wersji 4.

Pierwszym problemem okazał się brak pola confirmPassword  w klasie User. Poszperałem na forach i znalazłem w rozwiązania tego problemu:

  1. Stworzyć dodatkowe pole w klasie User  – confirmPassword
  2. Stworzyć dodatkową klasę, przypuśćmy CreateUserForm, mniej więcej tak:
class CreateUserForm {
String confirmPassword;
User user;
(... )
}

Rozwiązanie to wydaje mi się “ładniejsze” niż pierwsze, gdyż nie tworzymy w klasie, wykorzystywanej przy każdym requescie pola, które w ogóle nam jest niepotrzebne.

Kolejnym problemem okazała się walidacja. Chcieliśmy w 100% korzystać z funkcjonalności, jakie dają nam adnotacje z Hibernate Validatora. Brakuje jednak tam adnotacji umożliwiającej porównywanie ze sobą 2 pól.

Tutaj też skorzystałem z forów. Jedna osoba z teamu hibernate poleciła mi wykorzystanie constraintów (przepraszam za nieprzetłumaczenie :)) przypisanych do klas i zmianę domyślnego błędu zwracanego przez ten walidator.

Poniżej przedstawię rozwiązanie od jakiego doszedłem:

Poniżej znajduje się definicja interfejsu odpowiedzialnego za adnotację @SamePassword

@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = SamePasswordValidator.class)
public @interface SamePassword {
String message() default "{pl.aetas.gamestore.validator.constraint.SamePassword}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

Sama klasa walidatora wygląda tak:

public class SamePasswordValidator implements ConstraintValidator<SamePassword, Object> {
SamePassword constraintAnnotation;
public boolean isValid(Object value, ConstraintValidatorContext context) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(constraintAnnotation.message()).addNode("confirmPassword").addConstraintViolation();
CreateUserForm u = (CreateUserForm) value;
if (u.getConfirmPassword().equals(u.getUser().getPassword())) {
return true;
}
return false;
}
public void initialize(SamePassword constraintAnnotation) {
this.constraintAnnotation = constraintAnnotation;
}
}

Aby skorzystać z w/w rozwiązania wystarczy w klasie CreateUserForm dodać adnotację @SamePassword (na poziomie klasy) i .. tyle 🙂

Mam nadzieję, że komuś się to przyda. W naszym projekcie adnotacje znacznie zwiększyły czytelność kodu, a jest to bardzo istotne przy pracy grupowej.

Spring 3.0.0 RC3 ujrzał światło dzienne

Wczoraj tj 1 grudnia 2009 roku światło dzienne ujrzała trzecia wersja RC Spring Frameworkwa.

Z tego co udało mi się zauważyć, poprawiona została implementacja namespace’a mvc, a konkretnie mvc:annotation-driven, która sprawiała mi problemy w wersji RC1. Poza tym poprawiono sporo innych błędów. Pełny changelog znajduje się na stronie: http://www.springsource.org/node/2198 .

Mam nadzieję, że jest to już ostatnia wersja kandydująca i następną wersją będzie wersja GA 🙂

Testowanie ze Springiem – nowa porcja wiedzy :)

Chciałbym napisać nieco więcej na temat testowania w Springu i przytoczę tutaj kilka luźno związanych, ale wartych zapamiętania reguł.

Przede wszystkim, kiedy tworzymy testy integracyjne i tworzymy kontekst aplikacji musimy wiedzieć, że kontekst ten tworzony jest raz na cały cykl testów. Jest to ważne, gdyż czasem stan naszych beanów może się zmienić podczas testów i może to powodować nieprawidłowe wykonywanie kolejnych testów. Aby zapobiec temu problemowi wykorzystujemy dodatkową adnotację:

@DirtiesContext – adnotacja do metody, która określa, że konspekt aplikacji mógł zostać zmieniony przez test i musi zostać konspekt musi zostać stworzony od nowa.

Ogólnie sam fakt, że kontekst tworzony jest raz jest bardzo korzystny dla nas, gdyż skraca to znacznie czas wykonywania testów.

Poniżej opiszę jeszcze 2 ciekawe adnotacje, które znacznie rozszerzają możliwości testów.

Pierwszą z nich jest:

@Timed(millis=1000) – która, jak można się domyślić, określa w jakim maksymalnym czasie, test ma zostać wykonany. Jeżeli test wykonuje się dłużej, nie jest on spełniony.

@Repeat(10) – test wykonywany jest wielokrotnie (w tym wypadku 10 razy) i tylko w przypadku, gdy wszystkie 10 testów przejdzie, test zostanie spełniony.

Nie jest to cała lista adnotacji, jednakże  są to najciekawsze (wraz z tymi z poprzedniego wpisu) wg mojego uznania 🙂

Po więcej odsyłam do referencji Springa 🙂

Java – Spring 2.5.6 testowanie DAO z użyciem adnotacji

Ostatnimi czasy siedzę trochę w Spring Framework, frameworku dla Javy. Doszedłem do etapu testów i stwierdziłem, że godnym opisania będzie sposób testowania metod opartych o transakcje, gdyż ciekawym jest fakt iż wszystko co odbywa się w danych testach (dodawanie danych, edycja itd.) jest następnie cofane do wersji pierwotnej (wywoływany jest rollback na transakcji) i dzieje się to automatycznie.

Poniżej znajduje się przykładowa klasa wraz z metodami testującymi. Wszystko oparte jest na adnotacjach, więc nie ma problemu:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:test-config.xml"
public class UserAccountDaoImplTest {
    @Resource
    UserAccountDaoImpl userAccountDaoImpl;
    @Test
    @Transactional
    public void testSaveUser() {
        System.out.println("saveUser");
        UserAccount transientInstance = new UserAccount();
        transientInstance.setEmail("email@mail.con");
        transientInstance.setEnabled(true);
        userAccountDaoImpl.saveUser(transientInstance);
        UserAccount userFromDb = userAccountDaoImpl.getByEmail("email@mail.con);
        assertNotNull("User should be not null", userFromDb);
assertTrue("User should be enabled", userFromDb.isEnabled());
        assertTrue("User should be non locked", userFromDb.isAccountNonLocked());
    }
    @Test(expected = ConstraintViolationException.class)
    @Transactional
    public void testSaveUserDuplicateEmail() {
        System.out.println("saveUserDuplicateEmail");
        UserAccount transientInstance = new UserAccount();
        transientInstance.setEmail("michal@somedomain.pl");
        userAccountDaoImpl.saveUser(transientInstance);
    }
    @Test
    @NotTransactional
    public void testGetUserById() {
        System.out.println("getUserById");
        long id = 1L;
        UserAccount result = userAccountDaoImpl.getUserById(id);
        assertNotNull("User with id " + id + " should be found", result);
        assertEquals(new Long(id), result.getId())        id = 667L;
        result = userAccountDaoImpl.getUserById(id);
        assertNull("User with id " + id + " should not be found", result);
    @Test(expected = UsernameNotFoundException.class)
    @NotTransactional
    public void testGetByEmailNoUser() {
        System.out.println("getByEmailNoUser");
        String email = "someone@gnail.con";
        userAccountDaoImpl.getByEmail(email);
    }
}

Początkowo inicjujemy kontekst springa (definiujemy która klasa się tym zajmie i dodajemy plik konfiguracyjny).

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:test-config.xml”)

Następnie musimy wstrzyknąć do testu instancję którą testujemy, wykorzystujemy do tego adnotację @Resource:

@Resource
UserAccountDaoImpl userAccountDaoImpl;

Nie będę tutaj opisywał adnotacji czystego JUnita, zwrócę jedynie uwagę na adnotacje potrzebne przy testowaniu danych opartych o DB. Tak więc mamy:

@Transactional – określa nam, że dana metoda korzysta z transakcji i ma być wykonany rollback
@NotTransactional – odwrotnie do tego wyżej 🙂

Dodatkowo, co nie zostało pokazane na powyższym przykładzie, możemy skorzystać z adnotacji @Rollback(false) jeżeli nie chcemy, aby wykonywany był rollback po wykonaniu testu.

Mam nadzieję, że powyższy (działający u mnie) przykład komuś się przyda. Ja chwilę spędziłem, zanim doprowadziłem go do porządku, choć okazało się to niezwykle proste (wynik końcowy) 🙂

Backgammon – odbicia kostek

Dziś udało mi się ukończyć prawie w całości etap związany z samą grą (przenoszeniem  i zbijaniem pionków, “wyrzucaniem pionków poza planszę itd.). Jestem lekko znużony ciągłą refaktoryzacją kodu i pisaniem czegoś, czego efektów nie widać na pierwszy rzut oka.

Zająłem się więc dodawać efekty 🙂

Efektem, który znacznie podnosi realizm gry są odbicia. Jako, że plansza będzie lekko wypolerowania, będzie w niej widać delikatne odbicia kostek. Poniżej krótki filmik pokazujący na zwykłej płaszczyźnie odbicia kostek.

Docelowo odbicia będą tylko na planszy. Pomyślę też nad “polerowaniem” pionków i innych elementów 🙂

Odbicie to jest prostym do osiągnięcia efektem, polegającym na przekształceniu elementów (w tym przypadku kostek), względem pewnej płaszczyzny, a następnie odrysowanie tej płaszczyzny z włączonym mieszaniem kolorów (GL_BLEND), czyli wykorzystaniem przezroczystości. W rzeczywistości każda kostka renderowana jest dwukrotnie (oryginalny obiekt + odbicie).

Miałem to zrobić jutro, ale z powodu bezsenności udało mi się przenieść efekt odbicia pionków na docelową planszę. Aktualnie odbicia są może zbyt widoczne, ale to tymczasowe rozwiązanie, żeby zaprezentować efekt 🙂 Zapraszam do obejrzenia poniższego filmiku.

Playstation 3 Slim

No i stało się. Długo oczekiwany przeze mnie PS3 slim ujrzał światło dziennie na konferencji Gamescom w Kolonii. Nowa wersja jest 33% mniejsza, 36% lżejsza i … ok . 25% tańsza. W USA cena ustalona została na 299$, w Europie na 299€ (ach ten wspaniały przelicznik $1:€1).

Playstation 3 Slim

Playstation 3 Slim

Konsola wygląda identycznie, jak na zdjęciach z niedawnych przecieków.

Teraz rozpocznie się czas oczekiwania, kiedy znów będę mógł cieszyć się PS3 we własnym domu 🙂

Nokia porzuci Symbiana?

Niemiecki Financial Times (FT) powołując się na informacje zdobyte od pewnej osoby związanej z Nokią pisze, iż Nokia zamierza porzucić Symbiana i podążyć w stronę Maemo – systemu, który obecnie stosowany jest w tabletach Nokii.

Financial Times cytuje swoje źródło z Nokii:

Symbian jest zbyt nieefektywny (trudny w rozwoju), aby nadążyć za nowoczesnymi systemami operacyjnymi. Musimy coś z tym zrobić.

Nokia oficjalnie nie wypowiedziała się na ten temat, a jedynie “wstrzymała się od komentarzy”. To posunięcie Nokii byłoby jednak bardzo rozsądne, gdyż telefony Nokii z Symbianem na pokładzie nie mogą dorównać nowym telefonom z alternatywnymi systemami.

Po więcej informacji odsyłam do źródła.

Studencki PS3 dev kit

14 lipca 2009, na konferencji SCEE R&D ’09 Sony przedstawiło PS3 Academic Development Programme . W chwili obecnej program jest w fazie zamkniętej bety. Jako mini-dev-kit dostępna ma być pełnowymiarowa konsola z 2 USB i zainstalowanym SDK.

Sony, udostępniając mini dev kit chce dotrzeć do uczelni wyższych, aby mogły w łatwiejszy sposób pogłębiać swoją wiedzę na temat tworzenia aplikacji (gier :)) na PS3. Dotychczas jedyną możliwością tworzenia na platformie PS3 i w architekturze procesora Cell, było programowanie w systemie linux, który może być zainstalowany na konsoli.

Nie wiem czemu przeoczyłem ten wątek, gdyż od dawna czekałem na jakieś wieści dotyczące dostępu do SDK Sony. Wątek więc spóźniony, ale jak najbardziej aktualny i ciekawy!

Nvidia PhysX Visual Debugger

Dotychczas moje debugowanie Physx’a ograniczało się do debugowania kodu c++ i ręcznego dopasowywania brył otaczających obiekty, które chciałem uwzględnić przy obliczaniu kolizji.

Dziś wpadł mi w ręce PhysX Visual Debugger firmy NVidia. Aplikacja ta zdalnie debuguje scenę stworzoną przy użyciu silnika Physx. Wizualizuje ona zarówno aktorów (obiekty, z którymi liczone są kolizje) jak i wiele innych parametrów, w tym:

  • bryły otaczające – bryły, z którymi przeprowadzane są uproszczone testy kolizji
  • wektory prędkości
  • stan obiektu – pokazuje, czy obiekt jest uśpiony, czy występuje kolizja z innym obiektem itd.
  • itd.

Dodatkowo debugger pokazuje wszystkie parametry aktorów, dzięki czemu możemy w łatwy sposób wychwycić błąd.

Dzięki tej aplikacji udało mi się zauważyć błąd w tworzonej obecnie grze backgammon, którego nie dało się zauważyć inaczej, a który powodował dziwne zachowywanie się pionków.

Poniżej krótkie wideo z testowania gry z wykorzystaniem Physx Visual Debugger.

PhysX Remote Debugger dostępny jest do ściągnięcia na stronie: http://developer.nvidia.com/object/pvd_home.html