31 grudnia 2011

17b 79 63 7a 65 6e 69 61 20 6e 6f 77 6f 72 6f 63 7a 6e 65

3 komentarzy
Właśnie dobiega końca 2011 rok i nadeszła pora na życzenia noworoczne. Ostatnio siedzę nad reprezentacją liczb całkowitych w Javie, więc nie inaczej mogło być i dzisiaj (w końcu to taka uroczysta pora, która wymaga specjalnego potraktowania :-))
1010011 1111010 1100011 1111010 100011001 101011011 1101100 1101001 1110111 1100101 1100111 1101111
100000
1001110 1101111 1110111 1100101 1100111 1101111
100000
1010010 1101111 1101011 1110101
100000
110010 110000 110001 110010
100000
101111100 1111001 1100011 1111010 1111001
100000
1001010 1100001 1100011 1100101 1101011
100000
1001100 1100001 1110011 1101011 1101111 1110111 1110011 1101011 1101001
100000
1111010
100000
1110010 1101111 1100100 1111010 1101001 1101110 100000101 101110
Do odkodowania można skorzystać z poniższej aplikacji.
package pl.japila.java7;

import java.util.Scanner;

import javax.swing.JOptionPane;

public class ZyczeniaNoworoczne {

    public static void main(String... args) {
        String userInput = JOptionPane.showInputDialog(null,
                "Wprowadź dane do odkodowania (zastosuj zasadę Copiego & Paste)");

        StringBuilder zyczeniaNoworoczne = new StringBuilder();

        Scanner scanner = new Scanner(userInput);
        while (scanner.hasNext()) {
            zyczeniaNoworoczne.append((char) Integer.parseInt(scanner.next(), 2));
        }

        JOptionPane.showMessageDialog(null, zyczeniaNoworoczne);
    }

}
p.s. Do odkodowania tytułu zastosuj podstawę 16 w linii 17.

30 grudnia 2011

O kodzie uzupełnień do dwóch w Javie raz jeszcze

0 komentarzy
W Kod uzupełnień do dwóch w Javie (reprezentacja binarna liczb całkowitych) zaprezentowałem moją dotychczasową wiedzę na temat reprezentacji binarnej liczb całkowitych w Javie. Uważam to za mój początek w dokładniejszym rozpoznaniu tematu i nie ukrywam, że wciągnął mnie. Przypomnę tylko, że zaczęło się od zmian w Javie 7 z Fork/Join (nowe podejście do współbieżności w Javie z konstrukcjami wyższego poziomu), aby przez operator przesunięcia w prawo bez znaku >>> przejść do kodu uzupełnień do dwóch dla liczb całkowitych w Javie. Właśnie takie przejścia z jednego tematu na drugi w krótkim czasie lubię najbardziej. Nie pozwalają człowiekowi na dłuższy bezruch.

Przez ostatni tydzień dalej zgłębiałem temat i przesiedziałem sporo czasu czytając różnej maści artykuły. O większości pisałem na swoim kanale @jaceklaskowski na twitterze, więc wielu już miało przedsmak tego, o czym teraz będę pisał.

Prawie.

Liczby całkowite w Javie

Specyfikacja The Java Language Specification, Third Edition w rozdziale 4.2.1 Integral Types and Values wymienia typy całkowite z ich zakresami. W kolejności ich długości wyróżniamy: byte na 8 bitach, short na 16 bitach, int na 32 bitach i najdłuższy long na 64 bitach. Jest jeszcze całkowite char, które reprezentowane jest na 16 bitach, z tą różnicą, w porównaniu do poprzednich, że bez bitu znaku (najstarszy bit, pierwszy od lewej strony, albo ostatni z prawej).

I już przy omawianiu dostępnych typów dostrzec można ich różną reprezentację wewnętrzną - byte, short, int i long są z bitem znaku, w przeciwieństwie do char, któremu dano wszystkie dostępne bity do dyspozycji.

Dodawanie i liczba przeciwna w kodzie uzupełnień do dwóch

W artykule na Wikipedii Two's complement trafiłem na zdanie, które wywarło na mnie niesamowite wrażenie i sprawiło, że zrozumiałem sens istnienia tego systemu kodowania. Uważam, że mogłoby stanowić świetne wprowadzenie dla całego artykułu, albo jedyne:

"Two's complement numbers is a way to encode negative numbers into ordinary binary, such that addition still works."

Tylko o jakie dodawanie chodzi?!

Właśnie o zwykłe dodawanie binarne się rozchodzi. Jak mogłem się zorientować przeszukując materiały w Sieci, istnieje wiele systemów reprezentowania liczb całkowitych, ale czy to podwójne zero, czy konieczność rozróżniania znaku dodawanych liczb, sprawiają, że kod uzupełnienia do dwóch wydaje się być najbardziej trafnym. I taki zastosowano w Javie.

W Signed Int: Two's Complement mogłem dalej zgłębiać niuanse kodu uzupełnień do dwóch, który od tej pory będę zapisywał jako 2C (od angielskiego two's complement). Tam dowiedziałem się, że w 2C występuje jedno zero i dodawanie jest spójne dla reprezentacji bitowej z i bez znaku korzystając ze sprzętowej realizacji dodawania bitów (bez względu, czy reprezentują liczbę ze znakiem, czy bez - obie reprezentacje sprowadzane są do reprezentacji bez znaku). Ta cecha 2C jest związana z działaniem sprzętowym dodawania, a tutaj moja wiedza kończy się niezwykle szybko i na tym poprzestanę. I czuję, że więcej nie jest mi potrzebne o maszynowych rozwiązaniach.

Zadanie dla dociekliwych: wykonaj bitowe dodawanie liczb całkowitych, np. 1 i 2.

Najdłuższa liczba całkowita - typu long - ma do dyspozycji 64 bity. Pierwszy bit zarezerwowany jest dla bitu znaku (poza char).

Do uzyskania liczby ujemnej w 2C mamy 3 różne sposoby, z których najczęściej brany jest ten, który polega na odwróceniu wszystkich bitów i dodaniu jedynki, tj. -B = ~B + 1, przy założeniu, że B to dowolna liczba całkowita.

Zadanie dla dociekliwych: znajdź liczbę przeciwną do 1 korzystając z powyższego algorytmu.

I właśnie w tym momencie dociera do mnie jak interesującym jest rozpoznawanie tematu reprezentacji 2C. Dodaj 1 do liczby, której reprezentacja bitowa zawiera wyłącznie 1ki (czyli -1).
1111 1111 1111 1111 1111 1111 1111 1111     // -1
+ 0000 0000 0000 0000 0000 0000 0000 0001     //  1
-------------------------------------------------------------------
 10000 0000 0000 0000 0000 0000 0000 0000     //  0 (na 33 bitach = przepełnienie!)
Obie liczby są typu int. Obie mają do dyspozycji 32 bity z ostatnim bitem (licząc od lewej) zarezerwowanym na znak. Wynik również musi mieścić się w 32 bitach, ale cóż to?! Dodawanie 1 i -1 kończy się przepełnieniem - wynik wymusza 33 bity. W Javie taka sytuacja jest ukrywana przez usunięcie dodatkowego 33 bitu, aby w ten sposób otrzymać liczbę 32-bitową, która składa się wyłącznie z samych 0, a to po prostu 0 w systemie dziesiętnym. Jakież to piękne!

Idąc dalej, możnaby zastanowić się, co stanie się przy wyznaczaniu liczby przeciwnej dwukrotnie? Czy zachodzi zasada wyznaczania liczby przeciwnej podwójnie, która powinna wyznaczyć liczbę początkową, czyli -(-x) = x, w 2C?

Krok 1. Reprezentacja liczby całkowitej w postaci 32 bitów (dla int) lub 64 bitów (dla long). Ja pozostanę przy 32 bitach.

int n0 = 1111 1111 1111 1111 1111 1111 1111 1111 // -1

Krok 2. Odwracamy wszystkie bity

int n1 = 0000 0000 0000 0000 0000 0000 0000 0000 // 0

Krok 3. Dodajemy jedynkę

int n2 = 0000 0000 0000 0000 0000 0000 0000 0001 // 1

Zakończyłem pierwsze wyliczenie liczby przeciwnej do zadanej, czyli -1. Czy kontynuując odwracanie wyliczę wyjściową, czyli -1?

Krok 4 Reprezentacja bitowa liczby 1

int n00 = 0000 0000 0000 0000 0000 0000 0000 0001 // 1

Krok 5 Odwrócenie bitów

int n10 = 1111 1111 1111 1111 1111 1111 1111 1110 // nieistotne

Krok 6 Dodajemy jedynkę

int n20 = 1111 1111 1111 1111 1111 1111 1111 1111 // -1

I jak łatwo zauważyć n20 == n0, czyli parzyste wykonanie wyznaczania liczby odwrotnej do zadanej zawsze zwróci liczbę początkową.

Z Why computers represent signed integers using two’s complement tylko upewniłem się, że 2C jest warte poświęconego czasu i jego zrozumienie uważam od tej pory za obowiązkowe (ja już mam za sobą, więc tym łatwiej jest mi rzucać takie stwierdzenia :)).

"The representation of signed integers is the representation used by modern processors. It is called "two's complement" because to negate an integer, you subtract it from 2N. For example, to get the representation of –2 in 3-bit arithmetic, you can compute 8 – 2 = 6, and so –2 is represented in two’s complement as 6 in binary: 110."

W tym zdaniu znajduje się kolejny sposób na wyznaczanie liczb przeciwnych w 2C. Po prostu odejmujemy liczbę dodanią od 2^N, czyli dla 32 bitowych liczb typu int będzie to 1 + 32 zera w binarnej reprezentacji (wyznaczenie, a co ważniejsze, zapamiętanie tej liczby stanowi nie lada wyzwanie umysłowe, więc pozostańmy przy takim opisie).

Z Kod uzupełnień do dwóch w Javie (reprezentacja binarna liczb całkowitych) wiemy, że mnożenie
package pl.japila.java7;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;

public class TwoCDemo {

    @Test
    public void test() {

        long oneAnd32Zeros = (long)1 << 32; // 0x1_FFFF_FFFF - int overflow!
        int three = 3;  // 0b11
       
        int minusThree = (int)(oneAnd32Zeros - three);
       
        assertThat(minusThree, is(-3));
    }

}
Jako podsumowanie, warto zwrócić uwagę na użycie operatora przesunięcia w lewo, aby uzyskać liczbę podwójnie większą od największej w zakresie int. Nie chciałem pisać tej liczby dziesiętnie, a (czego nie wiedziałem wcześniej) jej reprezentacja w notacji bitowej (z 0b), ósemkowej (z wiodącym 0), albo szesnastkowo (z 0x) nie jest możliwa - są one zarezerwowane wyłącznie dla typów int i mniejszych.

23 grudnia 2011

Kod uzupełnień do dwóch w Javie (reprezentacja binarna liczb całkowitych)

7 komentarzy
Wszystko zaczęło się od mojego przedstawienia zmian w Javie 7, w pakiecie java.util.concurrent podczas 84 spotkania Warszawa JUG - Warszawski Eclipse DemoCamp 2011 - Java 7, JavaFX i Eclipse (prezentacja do pobrania jako JacekLaskowski-EclipseDemoCamp2011-ConcurrencyUtilitiesJava7-2011.11.08.pdf).

Wtedy zaczęła się moja przygoda ze szkieletem Fork/Join. Rozwiązywanie problemu przez zrównoleglanie jego mniejszych składowych wymaga właściwego sposobu podziału (zwykle po połowie) i tak do ustalonego, minimalnego poziomu jego złożoności, a właściwie braku, po którym rozwiązanie można obliczyć "siłowo" (element po elemencie, liniowo).

Kwestią, z którym zwykle zmagają się programiści korzystający z Fork/Join (czy dowolnego problemu rozwiązywanego przez algorytmy typu "dziel i zwycieżaj") to, w jaki sposób dzielić, aby samo dzielenie nie było na tyle skomplikowane, że zysk ze zrównoleglenia zostanie przez niego skonsumowany i ostatecznie wyjdziemy na przysłowiowe "zero".

I tu pojawia się przyczynek do tego wpisu - operator przesunięcia bez znaku w prawo >>> (ang. unsigned right shift) w Javie.

Nie jest to niczym odkrywczym w Javie 7, ale przy Fork/Join nabrał większego znaczenia. Mówiąc wprost, ja na niego zwróciłem uwagę właśnie przy Fork/Join. I tak kończy się w zasadzie rola Fork/Join, które nie będzie już przywoływane, bo posłużył wyłącznie jako tło do rozpoznania operatora przesunięcia i jak się później okazało reprezentacji liczb całkowitych w Javie.

Weźmy następujący problem: W jaki sposób wyznaczyć połowę pewnej liczby nieujemnej x?

Liczba dowolna, acz ustalona, x (teraz dopiero dojrzałem, aby dostrzec piękno tych słów) może być liczbą elementów w tablicy, w którym znajdują się elementy do przetworzenia.

Operator przesunięcia w prawo bez znaku >>> jest złożeniem << i >> w zależności od znaku lewego argumentu - dodatni to >>, a ujemny...cóż...tu sprawa się komplikuje i wygląda (n>>s)+(2<<~s) przy założeniu, że rozważamy n>>>s.

Pamiętam, kiedy dostrzegłem (a właściwie pokazano mi palcem), że n << 1 to po prostu n * 2. Innych zastosowań przesunięcia w lewo jeszcze nie odkryłem, ale pewnie są równie zabójcze dla mojego serca :)

Wtedy zacząłem zgłębiać reprezentację liczb całkowitych w Javie, bo w końcu działanie tych operatorów polega na przesunięciach binarnych.

Zadanie wprowadzające: Czy znasz zapis binarny ujemnej liczby całkowitej w Javie? Niech to będzie -1 lub Integer.MIN_VALUE.

Właśnie wtedy zreflektowałem się, jak niewiele wiem na ten temat. Niewiele?! Delikatnie powiedziane. Nic nie wiem! Zabrałem się za lekturę specyfikacji języka Java (tutaj niewiele znalazłem poza ogólnikami), aby skończyć na pojęciach reprezentacjach liczb ze znakiem i bez oraz kod uzupełnień do dwóch (ang. two's complement).

I tak od rozpoznawania Fork/Join przeszedłem do operatora przesunięcia, aby skończyć na reprezentacji liczb całkowitych w Javie.

W ten sposób powstała moja implementacja zamiany binarnego ciągu znaków (bez wiodącego 0b, które doszło w Javie 7) do postaci liczby całkowitej w zapisie dziesiętnym. Klasa nie jest krótka, ale starałem się dobierać nazwy do ich przeznaczenia, więc sądzę, że stosunkowo łatwo będzie zorientować się, co miałem na myśli.

Przede mną analiza kodów źródłowych java.lang.Integer, która dostarcza większości z poniższych metod. Niedługo więcej w temacie, bo nie czuję, abym go wyczerpał (a mam wrażenie, że jedynie zdrapałem wierzchnią warstwę). Oczekuję uwag i wskazówek od życzliwego czytelnika (w czasie świąt niegodnym nie podzielić się miłym słówkiem).

Gdybyśmy już się nie widzieli, życzę najlepszego z okazji nadchodzących Świąt Bożego Narodzenia. Baw się i świętuj, aby wypoczęty wrócić do dalszych prac poznawczych.
package pl.japila.java7;

public class BinaryToDecimalIntDemo {

    static final char ZERO = '0';
    static final char ONE = '1';

    public static void main(String[] args) {
        for (int number = Integer.MIN_VALUE; number <= Integer.MIN_VALUE + 0xFFFF; number++) {
            String negativeNumber = Integer.toBinaryString(number);
            int intInDecimal = BinaryToDecimalIntDemo.getIntInDecimal(negativeNumber);
            assert number == intInDecimal;
        }
        for (int number = Integer.MAX_VALUE; number >= Integer.MAX_VALUE - 0xFFFF; number--) {
            String negativeNumber = Integer.toBinaryString(number);
            int intInDecimal = BinaryToDecimalIntDemo.getIntInDecimal(negativeNumber);
            assert number == intInDecimal;
        }
    }

    static int getIntInDecimal(String binary) {
        int sum = 0;
        boolean negative = false;
        char[] bits = binary.toCharArray();
        if (bits.length == Integer.SIZE) {
            if (isNegative(bits)) {
                negative = true;
                bits = subtractOne(invertBits(removeSignBit(bits)));
            }
        }
        for (int i = bits.length - 1, j = 0; i >= 0; i--, j++) {
            sum += calculateValueInBinaryRepAt(j, bits[i]);
        }
        return negative ? (sum == 0 ? Integer.MIN_VALUE : -sum) : sum;
    }

    private static char[] subtractOne(final char[] bits) {
        char[] newBits = new char[bits.length];
        System.arraycopy(bits, 0, newBits, 0, newBits.length);
        int i = newBits.length - 1;
        if (newBits[i] == ONE) {
            newBits[i] = ZERO;
        } else {
            newBits[i] = ONE;
            for (int j = i - 1; j >= 0; j--) {
                if (newBits[j] == ZERO) {
                    newBits[j] = ONE;
                } else {
                    newBits[j] = ZERO;
                    break;
                }
            }
        }
        return newBits;
    }

    private static char[] invertBits(char[] bits) {
        char[] newBits = new char[bits.length];
        System.arraycopy(bits, 0, newBits, 0, newBits.length);
        for (int i = 0; i < newBits.length; i++) {
            newBits[i] = (newBits[i] == ZERO ? ONE : ZERO);
        }
        return newBits;
    }

    private static char[] removeSignBit(char[] bits) {
        char[] newBits = new char[bits.length - 1];
        System.arraycopy(bits, 1, newBits, 0, newBits.length);
        return newBits;
    }

    private static boolean isNegative(char[] bits) {
        return bits.length == Integer.SIZE && bits[0] == ONE;
    }

    private static double calculateValueInBinaryRepAt(int i, char c) {
        return Math.pow(2, i) * Character.getNumericValue(c);
    }

}

18 grudnia 2011

Relacja z cracow.mobi w Krakowie

12 komentarzy
Dzień rozpocząłem dosyć wcześnie, bo aż o 5:30 i było to zdecydowanie za wcześnie, aby wystąpić jako prelegent na konferencji, jeśli dodać wydarzenia poprzednich dni

Dzień wcześniej poprowadziłem prezentację na temat IBM WebSphere Application Server V8 u jednego z klientów IBM na południu Polski (nazwa i miejsce nie mają znaczenia, więc pozostańmy przy anonimowych nazwach). Tym razem pobudka o 4:45, aby wyrobić się na 6:17 na pociąg. Oczywiście dzień wcześniej również zeszło mi się do po północy przed kompem. Wszystko takie interesujące i ekscytujące, że kiedy przychodzi wieczór i rodzinka kładzie się spać, albo część już dawno śpi, cisza zapada i tak się siedzi, i siedzi, i siedzi, aż zegar wybija północ (!) Pamiętam, jak uporałem się z tym problemem kilka miesięcy temu, kiedy regularnie chodziłem spać około 22, aby zrekompensować "straty" pobudką wcześnie rano. I człowiek wyspany, i jakoś spokojniej z rana, i wszystko takie dopiero budzące się do życia, a dorzucając do tego, że wszystko działo się w lato, kiedy słońce gorąco prażyło, aż się chciało w tym wszystkim uczestniczyć!

Zmęczenie jest zdecydowanie niewskazane przy jakiejkolwiek aktywności, a ta, która wymaga pełnego skupienia i udziału publiczności, jak wystąpienie na konferencji, jest nadzwyczaj niebezpieczna w takim stanie. Potrafi wydrenować ostatnie resztki energii.

Do Krakowa dotarłem na czas - 10:15. Niedługo po rejestracji trafiłem na Radka Holewę! Jakież było moje zdumienie widząc jego wesołą twarz, która musiała z pewnością kontrastować z moją, na której rysowało się postępujące (i sukcesywnie wyniszczające) zmęczenie. Moja ekscytacja spotkaniem z Radkiem jeszcze bardziej wpłynęła na moją kondycję (tak samo pozytywnie, co i negatywnie, więc możnaby założyć, że saldo pozostało bez zmian, ale wahnięcia również odciskają swoje piętno). Kilka późniejszych rozmów z Konradem "ktosopl", Andrzejem "ags" i dopiero co poznanym Bartkiem Filipowiczem (prelegentem po mnie) tylko pogarszało sprawę. Nawet gdybym o tym wiedział wcześniej, za nic i tak nie zrezygnowałbym z okazji zamienienia z nimi słowa. Właśnie podczas bezpośrednich spotkań dostrzegam ile tracę ślęcząc przed kompem zamiast wyjść "na miasto".

Za zmęczeniem przywlokło się inne "cudo" - niepokój o moje przygotowanie. Konferencja cracow.mobi była moją pierwszą, w której prezentacje były z bardzo wąskiego tematu - tworzenia aplikacji mobilnych na platformę Android. Do tej pory zwykłem brać udział w takich, na których poruszano zagadnienia związane z językiem Java, technologią Java EE i miękkimi technikami wytwarzania oprogramowania. Zakres tematyczny zwykle był na tyle obszerny, że trudno było porównywać poszczególne prezentacje pod względem merytorycznym. Pozostawała jedynie możliwość porównywania ich pod względem estetycznym - przygotowanie prelegenta w temacie, wygląd prezentacji i w ogóle interakcja z publicznością. To dawało stosunkowo obszerne pole do popisu (lub ukrycia swojego niewielkiego praktycznego doświadczenia).

To uzmysłowiłem sobie dopiero, kiedy zacząłem przyglądać się, w jaki sposób swoje tematy prezentują Konrad "ktosopl" Malawski i Marek Defeciński.

Konrad wystąpił z tematem "Deep dive into RoboGuice - beyond "Hello World" apps". Nie trudno było zauważyć jego ponadprzeciętną znajomość Androida - posługiwał się terminami androidowymi, jakby sam je tworzył i kilkukrotnie zapytany z sali, odpowiadał bez trudu. Słabiej, acz wciąż znośnie, wypadł prezentacyjnie. Kiedy wszedłem na salę, Konrad już mówił. Zacząłem uważnie przyglądać się, w jaki sposób przedstawiał temat, bo po raz pierwszy miałem możliwość zobaczyć go w akcji. I gdybym na pierwszym wrażeniu poprzestał i odpuścił sobie, to nota byłaby marna. Trudno było odgadnąć, jaki to temat wybrał sobie Konrad do przedstawienia. Tu miałem nie lada zagwozdkę. Przez pierwsze 30 minut Konrad przedstawiał Guice i założenia DI z @Inject. Ucieszyłem się z udziału Guice, a jednocześnie, przez cały ten czas, zachodziłem w głowę, co tak na prawdę skłania Konrada do jego omawiania. Koniec końców wszystkie prezentacje miały być z założenia o Androidzie, a tu czas mija, a o Androidzie ni widu ni słychu. Slajdy słabej jakości tylko pogarszały sprawę - wymagają dopracowania, bo prawie nic nie było widać. Trudno doszukiwać się problemu z projektorami, których ułożenie - jeden duży na dole i drugi na antresoli, oba z bardzo dobrą rozdzielczością - i sala, niewielka, acz dopasowana do liczby uczestników, gwarantowały komfort prelegentom i słuchaczom. W końcu nie wytrzymałem i zajrzałem do agendy - ma być o RoboGuice. Tego nie znałem. Ponownie podniosłem poziom zainteresowania na wysoki. I tak doczekałem się RoboGuice, aby na końcu doświadczyć testowania z nim. Konrad zasługuje na uznanie pod kątem jego obycia z Androidem i RoboGuice, ale na początku za bardzo odszedł od tematu i pod tym kątem zawiódł mnie. Widać potencjał prezentacyjny u Konrada i zrobię wszystko, co w mojej mocy, aby wziął udział w Confiturze 2012. RoboGuice wchodzi do mojego arsenału narzędziowego i z pewnością niebawem się nad nim będę rozwodził na tym blogu. Dzięki Konrad za inspirację!

Przerwa.

Całą prezentację Konrada przesiedziałem sam, aby móc w pełni skosztować jej smaków. Przesiadłem się do Radka, który rozmawiał z...Ryan'em Gosling'iem (!) Nie żartuję. Kolejny po mnie prelegent Bartek Filipowicz wygląda zupełnie, jakby zdjąć skórę z Ryan'a (nic nie ujmując jednemu czy drugiemu). Kto nie wierzy, niech zajrzy na stronę prelegentów cracow.mobi (na samym dole). Nie mogłem się powstrzymać i powiedziałem mu o tym. W ogóle nie widać było jego zdumienia. Bynajmniej u Radka. Podobno Bartek spotykał się z taką reakcją wcześniej. Nie mogłem zdjąć z niego oczu taki podobny! :) Później doszli do nas Andrzej i Konrad, któremu "sprzedałem" moją ocenę jego wystąpienia. Obiecał naniesienie poprawek. Może już na kolejną Confiturę? Gorąco będę go dopingował, aby zgodził się wziąć w niej udział. Konrad, mordo Ty moja, nie daj się prosić!

Po przerwie, mikrofon przejął Marek Defeciński z "Testowanie w systemie Android". Powiało nudą mimo, że temat i slajdy wręcz krzyczały, aby było inaczej. Gość ma wiedzę i doświadczenie w Androidzie - co do tego, nie mam żadnych wątpliwości, ale zdziwiłbym się, gdyby znalazły się osoby, które nie zarzuciłyby mu braku przygotowania od strony prezentacyjnej. Jak zwrócił uwagę Radek - 16 minut trwał wstęp o sobie! To jak za starych, dobrych czasów moich wystąpień, za które dostawałem cięgi. Później Marek zdecydował się na kod na żywo, ale z takimi wpadkami, że podziwiałem jego upór, aby go mimo trudności zaprezentować. Samoprezentacja przez 16 minut, niedziałające testy i w końcu uwagi odnośnie emulatora Androida, zmusiły mnie do zabrania głosu, aby wyprostować stwierdzenia o wolnym działaniu tego ostatniego. Jakoś w końcu musiałem zrekompensować sobie nudę! Można było odnieść wrażenie, że testy są złe, bo są baaardzo wolne w przypadku aplikacji androidowych. Jakkolwiek trudno mi potwierdzić tę tezę w ogólności, to w tym konkretnym przypadku Marek pracował na sprzęcie, na którym całe środowisko ADT wolno działało! Panowie i panie - nie twierdzę, że ADT to cudo inżynieryjne, ale nie łudźmy się, że procek i RAM to podstawa, aby poradzić sobie z takimi problemami. To na pewno nie pozwala na stwierdzenia, że testy są do kitu, bo...maszyna za wolna i kto je by tam robił.

Jakby tego było mało Marek przekroczył czas prezentacji o dobre 10 minut. Gdyby chcieć podsumować jego wystąpienie jednym zdaniem, to pozwoliłbym sobie na stwierdzenie, że w pewnym momencie stracił kontakt z horyzontem i zaczął pikować niebezpiecznie, ku niechybnemu rozbiciu. Szczęśliwie dla wszystkich nie doszło do niej - koniec wystąpienia nadszedł i ulga pojawiła się po obu stronach.

Mimo tylu gorzkich słów pod adresem Marka, cieszę się, że mogłem uczestniczyć w jego prezentacji, bo zgrabnie zaprezentował Robolectric, który wymaga android.jar, o którym wcześniej Konrad nie wspomniał, a jedynie pozwolił sobie na uwagi odnośnie niekompletności Android API, które kończą się komunikatami "Stub!". Jeśli dobrze rozumiem rozbieżność między Markiem i Konradem, to podobną sytuację mamy z bibliotekami Java EE 6 dostarczanymi przez GlassFish w repozytorium mavenowym, które są potrzebne przy kompilacji i odchudzono je o dostarczanie wyłącznie kompletnego API bez kompletnej implementacji. Nic nowego. Dzięki Marek za skorygowanie poprzednika! Już możesz szykować się na lipcową Confiturę!

Kiedy Marek zademonstrował uruchomienie testów z poziomu Maven'a z pomocą wtyczki Easy shell do Eclipse moja ogólna ocena prezentacji lekko się podniosła. Szkoda, że 30 minut prezentacji było do kosza.

Tak dotarłem do przerwy obiadowej. 1h nie pozwalała na wojaże po Krakowie w poszukiwaniu jedzenia, więc skoczyliśmy z Bartkiem "Ryan'em" do pobliskiej restauracji z kebabem. Zaczęło mnie jednak skręcać z obawy o moje przygotowanie, więc skończyło się na kilku gryzach i reszta wylądowała w koszu. Nerwy przed moim wystąpieniem kompletnie odebrały mi apetyt. Okazało się, że również i Bartkowi. Wspólnie przeszliśmy przez jego slajdy. To było dobre posunięcie, bo później okazało się, że nie dałem rady.

I w końcu moje wystąpienie. Pozostawiam jej ocenę samym uczestnikom. Była to moja pierwsza prezentacja o Androidzie, która pozwoliła mi przypomnieć sobie uczucie tremy, która wiąże gardło przed publicznym wystąpieniem. Na prawdę dało mi się to odczuć i samemu zwróciłem uwagę na mój łamiący się głos. Poprzedni prelegenci nie pozostawiali mi złudzeń, że wodolejstwo nie jest tu mile widziane. Machanie rękoma należy odłożyć na bok i oczekuje się prezentacji na wysokim poziomie. Raczej nie byłem przygotowany do tego.

Mimo wszystko jestem z niej zadowolony pod kątem zaangażowania kilku osób w jej przebieg (w ten sposób próbowałem markować niedostateczne przygotowanie). Udało mi się poznać Jurka "AsyncTask", Grzegorza "Service" i Pawła "wyciek Contextu". Pojawiło się jeszcze kilka innych osób, które zechciały zabrać głos, ale ich niestety nie poznałem z imienia. Brawa dla wszystkich. Życzyłbym sobie, aby cała trójca zechciała przyjąć moje zaproszenie na Confiturę. W ich wypowiedziach dało się słyszeć doświadczenie i pewność swoich tez. Takich ludzi potrzeba więcej, aby ich postawa prowokowała do dyskusji podczas konferencji, co ma służyć dalszej wymianie doświadczeń. Jeśli Panowie czytacie ten wpis, zachęcam do kontaktu. Sam też Was będę poszukiwał. Pawła znam już osobiście, a Grzegorza jedynie mailem, więc zostaje jeszcze Jurek.

Pod względem merytorycznym u mnie było...średnio. Jakim to doświadczeniem mogę się mienić, skoro moje przygody z Androidem zacząłem pół roku temu?! Za to pod względem czasowym wypadłem perfekcyjnie. Zacząłem punktualnie, przygotowany psychicznie i sprzętowo. I tak też skończyłem - równo o czasie. Temat mojej prezentacji "RESTful Android" był nietrafiony, bo zdryfował na tematykę współbieżności na Androidzie, ale skoro przed samym rozpoczęciem wspomniałem o tym, czuję się zrehabilitowany. Jeśli tylko nie uraziłem uczestników swoim poziomem merytorycznym, cieszę się, że mogłem ponownie doświadczyć tego błogiego uczucia braku pewności w moje przygotowanie merytoryczne.

Slajdy dostępne są jako JacekLaskowski-cracow.mobi-RESTful-Android-2011.12.09.pdf.

Po moim wystąpieniu podeszło do mnie dwóch programistów androidowych z Comarchu - Maciej i kolega, którego imienia nie zapamiętałem (wybacz), którzy przedstawili mi problemy z dużą liczbą View w Activity (ponad 80) i problemami z działaniem Galaxy S2. Niestety, mimo, że szukali pomocy u mnie, to nie trwało długo, abym zreflektował się, kto tu potrzebuje pomocy - to nie ja im, ale oni mnie mogą pomóc. Mam do nich kontakt i nie zawaham się go użyć! Takich ludzi chciałbym więcej jako prelegentów na Confiturze 2012. Muszę nad nimi popracować jeszcze, bo nieświadomi moich planów względem nich.

Tak zeszła mi prezentacja Bartka. Wybacz Bartek! Zaproszenie na Confiturę wciąż podtrzymuję, więc pozostajemy w kontakcie.

Tak też skończyła się ścieżka wykładowa, ale nie moje poznawanie nowych twarzy. Mimo, że to wciąż konferencja javowa, to mało było osób, które wcześniej znałem. Wciąż zachodzę w głowę, czy Android to pole dla dotychczasowych znajomych z branży? Jakoś niewielu para się Androidem i trudno mi teraz odpowiedzieć dlaczego. Frapuje mnie to, więc niebawem pewnie jakaś odpowiedź się znajdzie.

Na sam koniec trafiłem na kilku napaleńców konferencyjnych, którzy zapowiedzieli już organizację konferencji o urządzeniach inteligentnych w Katowicach! Pozdrowienia dla Piotra "kosarock" i Marcina! Nie tylko zaskoczyli mnie swoim zdeterminowaniem, ale również wyborem miejsca (a może przede wszystkim tego drugiego). Sądziłem, że Kraków i Wrocław promieniują na okolicę tak silnie, że trudno mówić o kolejnej inicjatywie w pobliżu. W samym Krakowie mamy już GeeCON z ekipą z Polish JUG, JDD Proidei z Andrzejem i Anią na czele, 33rd degree Grześka Dudy, teraz cracow.mobi, a jeszcze są SFI i Eclipse DemoCamp. Dodać do tego silne oddziaływanie Poznania (Eclipse DemoCamp, Code Retreat i potencjalnie GeeCON) oraz Warszawy (Confitura, warsjawa i Eclipse DemoCamp), i nie widzę miejsca na nową propozycję w środkowej i południowej Polsce (może za wyjątkiem Łodzi, w której ostatnio mieliśmy do czynienia z mobilization i Code Retreat). Gdybym tylko mógł oddać zapał katowickich organizatorów, to pewnie wielu z Was nie miałoby złudzeń, że w 2012 będzie się mobilnie działo w Polsce, a Katowice stanie się kolejnym miejscem konferencyjnym po cracow.mobi i mobilization. Będę ich wszystkich gorąco dopingował. Z tyloma konferencjami w okolicy, będzie więcej okazji na wymianę doświadczeń. Bardzo się z tego cieszę i kiedykolwiek poproszony o pomoc, zawsze chętnie jej udzielę. Zresztą organizatorzy odgrażali się, że już jestem zaproszony! Z pewną nieśmiałością przyjmuję zaproszenie. Dziękuję!

O 16:45 byłem już w pociągu, aby przed 21 pojawić się w domu. Zmęczony i podekscytowany cieszyłem się, że wcześniej odwołałem udział w Agile Development Day 2011 w Warszawie, które zaplanowane zostało na całą sobotę! Po prostu nie dałbym rady. Tak bardzo chciałem w nim uczestniczyć, że kiedy już się pojawiła w harmonogramie, okazało się, że nie dane mi w niej wziąć udziału. Tak bardzo chciałem móc zasiąść z Jakubem Nabrdalikiem w parze i przy akompaniamencie Krzyśka Jelskiego ponownie wczuć się w melodię TDD. Następnym razem.

Trójka organizatorów cracow.mobi: Mateusz, Maria i Łukasz, których miałem przyjemność poznać podczas konferencji stanęła na wysokości zadania. Jestem im niezwykle wdzięczny, że umożliwili mi wziąć udział w konferencji i to w zaszczytnej roli prelegenta. Niech to będzie dzień, w którym upewniłem się, że inwestycja mojego czasu w rozpoznanie Androida była dobrym wyborem. Nowa technologia, zupełnie nowa klasa urządzeń, nowi ludzie - w roli uczestników, prelegentów i organizatorów. Jestem pozytywnie naładowany na kolejne androidowe przyjemności. Nie mógłbym sobie wymarzyć lepszego zakończenia roku 2011!

Nagrania z konferencji mają być dostępne na kanale mobiledeveloperpl na YouTube. Zapraszam do ich oglądania i komentowania. Uwagi zawsze mile widziane. Już nie mogę doczekać się, kiedy tylko pojawi się nagranie z mojego wystąpienia. Oj wstyd mi, oj wstyd, że można było tak wiele, a dałem tak niewiele. Kolejne książki czekają na moją przychylność i kolejne pomysły na aplikacje. Końcówkę roku 2011 zaplanowałem androidowo.

15 grudnia 2011

ManagementFactory.getPlatformMXBeans() w Javie 7 i nauka generyków

4 komentarzy
Jestem technicznym recenzentem książki Java 7 New Features Cookbook przed jej oficjalnym wydaniem na początku 2012 (pisałem o tym w Pierwszy rozdział o Java 7 od Packt) i w rozdziale 9. Database, Security and System Enhancements trafiłem na metodę java.lang.management.ManagementFactory.getPlatformMXBeans().

Jej użycie od razu przykuło moją uwagę, przede wszystkim dlatego, że korzysta z typowego użycia typów generycznych w Javie. Zwykle generyki sprawiały mi trudność i postanowiłem tym samym sprawdzić swoją ich znajomość. Po przejrzeniu kodu źródłowego tej metody postanowiłem spróbować swoich sił i napisać własną metodę o podobnej funkcjonalności. Co jednak istotne, to zależało mi na użyciu generyków.

I tak powstała klasa poniżej.
package pl.japila.java7;

import static java.lang.System.out;

public class Demo {

    public static void main(String[] args) throws Exception {
        int i = getInstance(Integer.class);
        out.println("i=" + i);
    }

    public static <T extends Number> T getInstance(Class<T> clazz)
            throws InstantiationException, IllegalAccessException {
        return clazz.newInstance();
    }

}
Czy dostrzegasz błąd, który popełniłem? Czy potrafisz wskazać go bez uruchamiania tej klasy? Ja niestety nie wykazałem się odpowiednią dbałością o szczegóły i umknęło mi to jedno ważne założenie. A jak u Ciebie?

Przy okazji pisania tej klasy znalazłem również sposobność, aby przetestować skrót klawiszowy w Eclipse do utworzenia statycznego importu dla System.out - Cmd+Shift+M. Spróbowałem również odszukać tej funkcjonalności przez odpalenie Quick access i tam też to można znaleźć.


Dzięki Marcinowi Stachniukowi (z Agile Development Day) mogłem nauczyć się czegoś nowego o Eclipse! Dziękuję!

Przeczytałem wpis Marcina, skomentowałem go, zrecenzowałem rozdział, popróbowałem się z generykami i jeszcze zapamiętałem dwa skróty klawiszowe w Eclipse. Nie za dużo jak na jeden dzień?! :)

14 grudnia 2011

Wrażenia pokonferencyjne - o Eclipse DemoCamp w Poznaniu

3 komentarzy
Jak ten czas szybko płynie! Wydaje się, że to wcale nie tak dawno, kiedy pisałem o konferencji JDD w Krakowie, a to już prawie 2 tygodnie mija i dopiero teraz przedstawiam wrażenia z kolejnej, ze mną w roli prelegenta. Potwierdza się stara, dobra zasada, że zadania trzeba robić, a nie o nich mówić i w przypadków moich relacji pokonferencyjnych niestety nie udało mi się jej zastosować. Nadrabiam.

Dobrego złe początki

Że też zawsze muszę sobie wybrać temat na wystąpienie, w którym doświadczenie zdecydowanie odbiega od standardów, których oczekuje się od prezentującego! W końcu zejdę na serce od tego stresu :)

Do Poznania przyjechałem około 17:30 i wydawało się, że była to odpowiednia chwila. Jeśli jednak dodać do tego właśnie rozpoczynające się targi poznańskie (nie wiem, czy to były te targi, czy inne z puli wielu targów w Poznaniu), to niestety było to złe założenie. Kiedy taksówka zajechała przez dworzec, a później ślimaczym tempem dowlokła się pod drzwi pubu na Szyperskiej, było już dawno po rozpoczęciu Eclipse DemoCamp 2011 w Poznaniu.

Zastałem już tłoczną salę słuchaczami, którym Tomek Zarna przedstawiał karierę Eclipse. Nie miałem okazji wysłuchać jego prezentacji, bo nie tylko, że trochę głośno, że jedynie na przodzie można było usłyszeć, co ma do powiedzenia, ale też sama sytuacja spotkania z organizatorami: Natalią Klimasz i Łukaszem Stachowiakiem, a później Adamem Dudczakiem, aby jeszcze później trafić na Darka "egit" Łukszę i...patrz, że też musiałem zapomnieć imienia!...nie pozwalała na wsłuchiwanie się. Zresztą, kto by tam słuchał, kiedy można pogadać z dawno niewidzianymi znajomymi?! Trafiłem również w międzyczasie na Dawida Weissa, ale to było chyba już po jego prezentacji. Wszystkich gorąco pozdrawiam!

"Przebijanie" się przez wrzawę powodowało tylko dalsze jej nakręcanie, więc o rozmowie nie było co marzyć. Za głośno. Jednak próbowaliśmy, co później odbiło się na moim gardle. Do domu zajechałem w stanie, jakbym był po niezłej bibce.

Przysłuchiwałem się prezentacji Dawida, ale wciąż w zasadzie myślałem o moim przygotowaniu tematu i przyglądałem się reakcjom uczestników na to, co ma do powiedzenia. W sali znajdowały się dwa monitory, na których można było zobaczyć slajdy, ale tylko jeden miał obok prezentera, więc było nie lada wyzwaniem zdecydować się, gdzie patrzeć, aby widzieć, albo słyszeć (monitory były różnej rozdzielczości i ich ułożenie sprawiało, że miało to znaczenie). Miałem wrażenie, że atmosfera jest lekko akademicka, tzn. za bardzo nastawiona na odbiór, bez choćby chęci zadawania pytań, co sama atmosfera ogólnego zgiełku dodatkowo "sprzyjała".

Pizza time. Już wspólnie ze Szczecinianami. Spałaszowaliśmy kilka kawałków, aby dalej dywagować na tematy różne. Prezentacje sobie, a my sobie.

Wchodzę na scenę

Przyszła pora na moje wystąpienie. Sądziłem, że EDC to rodzaj spotkania, w którym dużo kodu jest wielce pożądane. Z drugiej strony zastanawiałem się, na ile skuteczny jest przekaz z otwartym IDE i kodowaniem na żywo. Tym razem postawiłem na to drugie. Miało być dużo IBM Rational Application Developer V8 z Java EE 6 na IBM WebSphere Application Server V8. I to był mój błąd. Właśnie przez te monitory i ogólną wrzawę. Kompletnie nie spodziewałem się takiego miejsca i atmosfery, w której ja miałbym prezentować Java EE 6 tworząc aplikacje na żywo. Chciałem dobrze. To wszystko ich wina :)

Najbardziej obawiałem się mojego przygotowania z JAX-RS (z zanurzonym Apache Wink w WAS V8), ale ostatecznie i tak nie pokazałem tego. Dzisiaj bardzo tego żałuję, bo mogło uzupełnić przekaz.

Zaczęły się problemy z mikrofonem - a to za głośno, a to za daleko i tym samym cicho, a ja potrzebowałem wolnych rąk do kodowania. W końcu się dopasowaliśmy - doszedłem do porozumienia z mikrofonem i zabrałem się za demo.

Zacząłem od prostej aplikacji webowej z servletem określonym przez @WebServlet. Zero deskryptora i tylko @WebServlet. Później urlPatterns i @WebFilter. Dalej przyszła pora na demonstrację @Stateless bez jawnego interfejsu biznesowego w ramach WAR. Dalej chwila z CDI i tak przeszliśmy z @EJB do @Inject (ciekawym, ile osób rozróżnia zastosowanie obu?) Dotarłem bodajże do @WebService wygenerowanym z POJO w projekcie javowym i na tym się zakończyła moja batalia o zademonstrowanie produktów IBM wspierających Java EE 6.

Nawet się nie obejrzałem i wnet było już po godzinie.

Losowanie

Na zakończenie organizatorzy przeprowadzili losowanie. Pamiętam, że losowano książki, bo podczas ich rozlosowywania zdążyłem tylko powiedzieć do Darka, że nigdy, ale to nigdy nie udało mi się czegokolwiek wygrać i chyba musiałem mówić to z takim przekonaniem, że kiedy skończyłem, padło "Jacek Laskowski".

Wygrałem książkę!

Cóż za radocha. Miałem do wyboru jedną i padło na "97 Things Every Programmer Should Know". To było doskonałe zakończenie mojego wystąpienia i całego spotkania mimo, że, jak się później okazało, nie był to wcale koniec.

Nocne dyskusje i powrót

Po zakończeniu prezentacji, siedzieliśmy jeszcze dłuższą chwilę. Rozmawialiśmy o różnych rzeczach, aż padło magiczne: "Wychodzimy na miasto". Trafiliśmy na rynek, gdzie przesiedzieliśmy do...4 nad ranem! (mam nadzieję, że nie naciągam, bo już sam nie jestem pewien do której siedzieliśmy). Szczecin odjechał. I ja również zasypiając nad ranem. To na prawdę bolało szczególnie, że zakończyło się moim przespaniem porannego pociągu do Warszawy. W końcu jednak dotarłem do niej i EDC przeszło do historii jako bardzo udane przedsięwzięcie. Upewniło mnie o potrzebie częstszego udziału w nich i coś mi mówi, że nie powinienem odstępować od publicznych wystąpień. Chyba zaczęły mi ponownie sprawiać niesamowitą przyjemność.


Dziękuję Natalii i Łukaszowi za zaproszenie. Możliwość wyłożenia mojej niewiedzy szerszej publiczności była bezcenna :) Czuję się zobowiązany!

05 grudnia 2011

j.u.concurrent.Phaser i wątek onAdvance w Java 7

9 komentarzy
Każdorazowo, kiedy przygotowywałem klasę wspomagającą rozpoznanie java.util.concurrent.Phaser jej uruchomienie wymagało dodania opcji -ea w konfiguracji uruchomieniowej w Eclipse. W ten sposób mogłem prezentować moje doświadczenia w postaci pojedynczej klasy z użyciem assert. To jednak wymagało ode mnie właściwej konfiguracji dla każdej uruchamianej klasy (!) Wystarczy jednak mała zmiana w konfiguracji JRE i po sprawie!


Podczas mojego ostatniego wystąpienia o zmianach w Java 7 w kontekście programowania współbieżnego, w którym przedstawiłem j.u.c.Phaser, padło pytanie o wątek, który uruchamia metodę protected boolean onAdvance(int phase, int registeredParties). Za pomocą tej metody kontrolujemy dostępność obiektu Phaser. Kiedy zwróci true, Phaser kończy swoje działanie. Dzięki niej, mamy również możliwość uruchomienia akcji podsumowującej fazę, kiedy ostatni wątek w danej fazie zgłosi swoje przybycie, a przed przejściem do kolejnej (jeśli takowa w ogóle nastąpi).

Podczas spotkania nie byłem w stanie odpowiedzieć na pytanie o wątek, w którym będzie uruchomiona metoda onAdvance(), co czynię teraz, w poniższej klasie.
package pl.japila.java7.concurrent.phaser;

import java.util.concurrent.Phaser;

public class PhaserOnAdvanceDemo {

    static class MyPhaser extends Phaser {
        String threadName;

        public void setOnAdvanceThreadName(String threadName) {
            this.threadName = threadName;
        }

        protected boolean onAdvance(int phase, int parties) {
            assert threadName.equals(Thread.currentThread().getName());
            return true;
        }
    }

    public static void main(String[] args) throws Exception {

        final MyPhaser phaser = new MyPhaser();

        assert 0 == phaser.getPhase();
        assert 0 == phaser.getRegisteredParties();
        assert 0 == phaser.getUnarrivedParties();

        final int parties = 2;

        phaser.bulkRegister(parties); // register 2 threads - main's and one more

        assert 0 == phaser.getPhase();
        assert parties == phaser.getRegisteredParties();
        assert parties == phaser.getUnarrivedParties();

        phaser.arrive(); // main thread arrives

        assert 0 == phaser.getPhase();
        assert parties == phaser.getRegisteredParties();
        assert 1 == phaser.getUnarrivedParties();

        Thread t = new Thread() {
            public void run() {
                phaser.arrive(); // this (sub)thread arrives
            }
        };
        phaser.setOnAdvanceThreadName(t.getName());
        t.start();

        t.join(); // wait till t dies

        assert phaser.isTerminated(); // onAdvance returned true, and hence phaser is terminated
        assert 0 > phaser.getPhase(); // phaser is terminated, and hence getPhase() returns negative number
        assert parties == phaser.getRegisteredParties();
        assert 0 == phaser.getUnarrivedParties();
    }

}
Zanim uruchomisz powyższą klasę, zastanów się, jaka może być odpowiedź. Zmiana kolejności uruchomienia phaser.arrive() ułatwia znalezienie odpowiedzi. Wystarczy przenieść linię 36 z phaser.arrive() dla głównego wątku, po t.join() w linii 50. Potrafisz wytłumaczyć dlaczego? Chętnie odpowiem na wyraźną prośbę (jej brak będzie oznaką znajomości odpowiedzi). Dla mnie to teraz taaaaakie oczywiste, ale trzeba było widzieć moją minę na prezentacji! :)

p.s. W nadchodzący piątek, 9 grudnia, występuję w roli prelegenta na konferencji Cracow.mobi z tematem RESTful Android. Będzie to moje pierwsze, androidowe wystąpienie, a 45 minut na prezentację uważam jedynie za możliwość nakreślenia tematu i jestem zmuszony do potraktowania go wyłącznie slajdami. Sugestie odnośnie sposobu i zawartości prezentacji tematu mile widziane.

02 grudnia 2011

O register() i bulkRegister(int) z j.u.concurrent.Phaser w Java 7

0 komentarzy
Przeglądając źródła j.u.concurrent.Phaser trafiłem na ciekawostkę, która z początku zaskoczyła mnie, ale kiedy się nad tym chwilę zastanowiłem, byłem nie mniej zdumiony swoim zdumieniem.

Phaser oferuje dwie metody do zarejestrowania uczestników faz - public int register() oraz public int bulkRegister(int parties).

Trudno zrozumieć, dlaczego dopiero przegląd kodu źródłowego Phaser uzmysłowiło mi, że pierwsza metoda - public int register() - jest specjalnym przypadkiem drugiej - public int bulkRegister(int parties), dla której parties = 1.

Mam wrażenie, że wynikało to z mojego błędnego zrozumienia działania tych metod, w którym sądziłem, że rejestracja jest w jakiś sposób związana z konkretnym wątkiem. Pamiętam, jak próbowałem przekazać to błędne rozumienie uczestnikom ostatniego spotkania Warszawa JUG i tylko ich czujność doprowadziła do mojego "Nie jestem pewien, jak to dokładnie działa", co w efekcie sprawiło, że zajrzałem do kodu źródłowego i teraz znam prawidłową odpowiedź (!)

A wystarczyło czytać javadoc dla Phaser ze zrozumieniem, w którym napisano:

"As is the case with most basic synchronization constructs, registration and deregistration affect only internal counts; they do not establish any further internal bookkeeping, so tasks cannot query whether they are registered. (However, you can introduce such bookkeeping by subclassing this class.)"

Proste? Teraz tak!

Poniższy przykład powinien pomóc zrozumieć problem bardziej. Od teraz już nie pomylę się i kolejna odsłona moich prezentacyjnych wyczynów wokół java.util.concurrent powinna nosić znamiona bardziej profesjonalnej :)
package pl.japila.java7.concurrent.phaser;

import java.util.concurrent.Phaser;

public class Phaser2Demo {

    public static void main(String[] args) throws Exception {
        final Phaser phaser = new Phaser();

        int parties = 3;
        for (int i = 0; i < parties; i++) {
            phaser.register();
        }

        assert 0 == phaser.getPhase();
        assert 3 == phaser.getRegisteredParties();
        assert 3 == phaser.getUnarrivedParties();

        Thread t;

        (t = new Thread() {
            public void run() {
                phaser.arrive(); // arrive and move on
            }
        }).start();

        t.join(); // awaits thread t's death

        assert 0 == phaser.getPhase();
        assert 3 == phaser.getRegisteredParties();
        assert 2 == phaser.getUnarrivedParties();

        (t = new Thread() {
            public void run() {
                phaser.arrive(); // arrive and move on
                phaser.arrive(); // arrive and move on
            }
        }).start();

        t.join(); // awaits thread t's death

        assert 1 == phaser.getPhase();
        assert 3 == phaser.getRegisteredParties();
        assert 3 == phaser.getUnarrivedParties();
    }

}
Coś niejasne? Wyjaśnić? Służę pomocą. Czym więcej pytań, tym więcej rozpoznania i tym lepsze moje zrozumienie tematu (oby i Twoje).

01 grudnia 2011

Zagadka z Rethrowing Exceptions with More Inclusive Type Checking w Java 7

7 komentarzy
Czytając bardzo krótki, acz treściwy wpis A New Java Exception Handling Idiom o nowej cesze Java 7 - Rethrowing Exceptions with More Inclusive Type Checking pomyślałem o pewnej zagadce, której próba rozwiązania wymusi choćby minimalne zrozumienie zmian wokół obsługi wyjątków w najnowszym wydaniu Javy 7. Takie perełki sprawiają, że określenie zmian jako niewielkich w tym wydaniu jest czymś, z czym mam kłopot, aby się zgodzić.

Zagadka:
package pl.japila.java7;

public class PreciseRethrowDemo {

    public static void main(String[] args) throws Exception {
        PreciseRethrowDemo demo = new PreciseRethrowDemo();
        demo.createFoo();
    }

    Foo createFoo() throws FooException {
        Bar bar = new Bar();
        try {
            return new Foo(bar);
        } catch (Throwable t) {
            t = new SubFooException();
            bar.cleanup();
            throw t;
        }
    }

    @SuppressWarnings("serial")
    static class FooException extends Exception {}
    @SuppressWarnings("serial")
    static class SubFooException extends FooException {}
    static class Foo {
        Foo(Bar bar) throws FooException {
            throw new FooException();
        };
    }
    static class Bar {
        void cleanup() {};
    }

}
Czy powyższe skompiluje się? Jeśli tak, jaki będzie rezultat? Odpowiedzi można umieszczać w komentarzach. Proszę o kolejne zagadki, jeśli spotkałeś/-aś się z podobnymi w obszarze obsługi wyjątków w Java 7.

p.s. Za kilka dni - 17 grudnia 2011 - kończy się możliwość podejścia do testowego egzaminu na Oracle Certified Associate, Java SE 7 Programmer. System wyliczył mi koszt na poziomie 61 USD i przy niekorzystnym kursie USD/PLN mimo wszystko planuję podejść do niego za 2 tygodnie. A Ty?

29 listopada 2011

85 spotkanie Warszawa JUG o zmianach w Java 7 - Adam z JVM i ja z j.u.c.Phaser

0 komentarzy
Warszawska Grupa Użytkowników Technologii Java (Warszawa JUG)
Zwykłem zapowiadać spotkania Warszawskiej Grupy Użytkowników Javy (Warszawa JUG), ale tym razem było inaczej - zapowiedzi nie było, a spotkanie i tak się odbyło. Jedynym źródłem informacji o spotkaniu, w którym Adam Michalik przedstawił temat "Zmiany JVM w Java 7", a ja wystąpiłem z "java.util.concurrent.Phaser praktycznie", była strona i forum grupy. Okazało się, że wystarczyło, aby przyciągnąć blisko 30 osób, wśród których dało się dostrzec osoby, których dawno nie widziałem. To może być dowodem na to, że grupa (ponownie) przeżywa okres rozwoju i ma się całkiem dobrze. Dodając do tego plany spotkaniowe na kolejne 3 edycje i możnaby wyciągać wnioski o jej (ponownym) rozkwicie. Coraz bardziej skłaniam się ku tezie, że bez niej wiele rzeczy nie byłoby mi dane poznać, a tak 2 godziny i mam podsumowanie - chociażby dzisiaj o Java 7 i invokedynamic.

Chciałbym wierzyć, że moja, dzisiejsza prezentacja była równie dobra merytorycznie i prezentacyjnie jak Adama, który stał się moim wzorem do naśladowania. Znalazłem w jego prezentacji kilka ciekawych elementów, które zamierzam wprowadzić do własnych, publicznych wystąpień. Przede wszystkim slajdy, które zawierały dużą dawkę rysunków. To już nie pierwszy raz, kiedy dostrzegam siłę wyrazu obrazków, rysunków, diagramów, itp. Wszystko, co nie jest tekstem warto rozważyć jako element uzupełniający i uatrakcyjniający prezentację. Dobrym rozwiązaniem byłą agenda w postaci diagramu. I ten stoicki spokój w głosie. Jest z czego, a raczej od kogo, czerpać pomysły. Dzięki Adam!

Gdyby ktoś jeszcze zechciał wyjawić, jak JRuby wykorzystuje invokedynamic, o którym Adam wspomniał, że pojawia się z generowaniem klas, aby było szybciej, byłoby jeszcze cudniej. Albo lepiej - niech to przedstawi na naszym spotkaniu. Dla przyjezdnych mogę zorganizować fundusze związane z przyjazdem.

Około 7 wszedłem na scenę z przedstawieniem java.util.concurrent.Phaser z Java 7. Sądziłem, że od ostatniego razu temat jest już mi bliżej znany na tyle wystarczająco, aby nikt mi nie "podskoczył", ale czy to styl, w którym przedstawiałem podstawy, którym łatwo dotarłem do publiczności, czy to błyskotliwość zebranych, ale nie trwało długo, kiedy moja pewność została mocno nadszarpnięta. W przyjemnej atmosferze padło kilka pytań uzupełniających, które położyły się cieniem na kilka wcześniejszych, moich stwierdzeń o Phaser. Bardzo podobała mi się ta dociekliwość uczestników, którzy jedynie w niewielkim stopniu używali java.util.concurrent - klasy Executor i współbieżne struktury. Zdziwiłem się, że nikt nie korzystał z CountDownLatch czy CyclicBarrier. Zabrakło mi mojego "mentora" z poprzedniego spotkania, który podjął się trudu nakreślenia różnic między CountDownLatch, CyclicBarrier i Phaser, kiedy dało się zauważyć moje braki. Takich ludzi cenię najbardziej. Chciałoby się mieć do nich dostęp częściej.

Jako sukces dzisiejszego spotkania traktuję rozmowę na temat przyszłych wystąpień z osobami, których parkiet WJUGa jeszcze nie gościł. Pozdrowienia dla Michała i Piotra, których zapisałem sobie jako kandydatów. Od razu wziąłem ich adresy mailowe, aby mi nie "uciekli" :)

Prezentacja z mojego dzisiejszego spotkania dostępna jest jako JacekLaskowski-WJUG-j.u.concurrent.Phaser-2011.11.29.pdf.

Zachęcam do dzielenia się swoimi doświadczeniami z poznawania czegoś nowego. Nie trzeba być geek'em, aby prezentacja poszła gładko, a częściej była przyczynkiem do dokładniejszego zgłębiania tematu. Czego mogłem dzisiaj doświadczyć. Daleko mi do znawcy tematu java.util.concurrent, a jednak kilku z uczestników dzisiejszego spotkania pozwoliło mi sądzić, że było to dla nich wartościowe. Wystarczy, abym kontynuował temat. Kolejne odsłony tematu współbieżności w Javie 7 już niebawem.

A teraz pora na Androida i podsumowywanie myśli w temacie mojej prezentacji "RESTful Android - aplikacja androidowa jako klient REST" podczas cracow.mobi w Krakowie. Będzie to moje pierwsze wystąpienie w temacie aplikacji mobilnych na Androida i bardzo chciałbym, aby nie było ostatnim. Jeśli jest coś, co wartoby zaprezentować, rozpracować, czy podobnie, napisz mi na priv. Szczególnie ciekawi mnie, czy jako uczestnik wolał(a)byś więcej kodu czy teorii? I ile to znaczy "więcej"? Niech to będzie przymiarka do najlepszej prezentacji o Androidzie, jaką udało Ci się kiedykolwiek zobaczyć! :)

27 listopada 2011

Łącząc przyjemności - o TDD i spacerze "nagraniowym" z Maksymem

2 komentarzy
Warto czasami przystanąć, zastanowić się i po prostu pomyśleć bez jakichkolwiek zewnętrznych "przeszkadzaczy". Doświadczyłem błogosławieństwa takich chwil niedawno dwukrotnie i nie mogłem uwierzyć, jak niewiele trzeba, aby mieć ich więcej.

Podczas konferencji JDD w Krakowie (czytaj Wrażenia pokonferencyjne - zacznijmy od JDD w Krakowie) miałem przyjemność uczestniczyć w sesji "TDD Coding Dojo" z Krzyśkiem Jelskim i Marcinem Zajączkowskim. Kiedy wracałem do domu pociągiem, a może jeszcze wcześniej, w taksówce, zacząłem zastanawiać się nad słowami Jakuba Nabrdalika, który kiedyś stanowczym tonem stwierdził, że nie da się robić TDD z już gotową aplikacją. Miałem wtedy wrażenie, że Kuba jest tak etycznie upośledzony przez TDD, że jedyną, słuszną drogą dla TDD jest zacząć od testów. Ja jednak bardzo nalegałem na możliwość dopisywania testów do gotowej aplikacji (projekt Apache OpenEJB), aby stworzyć siatkę bezpieczeństwa dla późniejszych prac przy zmianie kodu. Nie pomagał nawet mój wrodzony wdzięk. Po prostu, Kuba kończył taki pomysł stanowczym: "To nie będzie TDD" i tyle mi było z nim rozmawiać. Oj, jaki ja byłem na niego zły za takie potraktowanie. Nie żebym czuł jakąś zadrę do niego za to, ale po prostu nie mogłem zrozumieć, dlaczego to nie przejdzie.

I właśnie podczas powrotu do Warszawy, po sesji z Krzyśkiem i Marcinem, olśniło mnie! Wydaje mi się, że zrozumiałem ideę TDD. Wreszcie połączyłem teorię z praktyką i jakkolwiek nie było tego drugiego wiele, to wystarczyło, abym usnął tezę, która wydaje się zgodna z myśleniem Kuby (!) Nie zapomnę tej chwili, kiedy prawie wykrzyknąłem "Eureka!"

TDD stosujemy jako "zapalnik" zmian w aplikacji. Pojawia się test, nie przechodzi (czerwono), piszemy minimalistyczną implementację, taką, aby jedynie pozwoliła przejść testowi (pojawia się zielone), refaktoring i tak w kółko. Kiedy zastanowić się nad kolejnością zmian w aplikacji - najpierw test, później minimalnistyczna implementacja i tak, aż do znudzenia, to łatwo zrozumieć, że aplikacja ma tyle, aby jedynie/aż przeszły testy. Nic więcej. Jeśli jest więcej, to prawdopodobnie możemy liczyć się z miejscami niepokrytymi testami. Całkiem zrozumiałe, jeśli para programistów jest więcej niż początkująca w temacie programowania i TDD w ogólności.

Weźmy teraz działającą aplikację. Skoro działa, to każdy kawałek kodu, który mógłby wyglądać na potencjalny błąd...NIE jest błędem! Na pewno nie jest nim jeszcze. Gdyby już był, to pojawiłaby się poprawka i...po błędzie. I teraz pora na moje olśnienie - wręcz niemożliwym jest pisanie testów, które objęłyby wszystkie możliwe przypadki do przetestowania dla działającej aplikacji. Słyszałem o narzędziach automatyzujących, które prześwietlając kod wykrywają "zakręty" na if'ach i temu podobnych konstrukcji "rozgałęziających", ale, właśnie, to są automaty. Gdyby pisać je ręcznie, to nigdy nie wiadomo, czy jest ich wystarczająco wiele, aby powiedzieć, że jest ich wystarczająco wiele. Właśnie to odwrócenie zależności między testami a aplikacją jest problemem. Nie można mówić o odwróceniu zależności w przypadku TDD, gdzie zależnością aplikacji są testy. A może na odwrót? Tak czy inaczej, jeśli zakładamy, że dla testu sprawdzającego, czy zwrócono liczbę 5 piszemy kod, który po prostu zwraca 5, to nie ma szansy na pomyłkę. Kod może być dalej pod kątem zaawansowania funkcjonalnego, ale należałoby to odznaczyć jako...nadgorliwość. Oczekujemy 5, to nie ma potrzeby wywoływać usługi RESTowej, która zwraca 5, bo wystarczy zwrócić 5. Proste i oczywiste.

Czy moje zrozumienie TDD jest właściwe? Czy takiego myślenia oczekuje się od praktyków TDD? Chętnie poznam Twoją opinię. W komentarzach jest duuuużo miejsca na dywagacje.

Kolejnym momentem, w którym doświadczyłem momentu olśnienia był dzisiejszy spacer z Maksymem. Kolejny samotny spacer przez 1,5-2h to nie przelewki. Łazisz po utartych ścieżkach Lasu Kabackiego i tak idziesz, i idziesz, i idziesz. Można kota dostać.

Z drugiej strony, kilka dni temu odznaczyłem sobie kilka nagrań z konferencji do odsłuchania i wcale mi się nie uśmiechało odsłuchiwanie ich podczas siedzenia w domu. Każdorazowo, kiedy próbowałem usiąść nad nimi w domu, zawsze pojawiało się zniecierpliwienie i w ogóle ogólna niechęć do ślęczenia przed kompem i gapienia się w monitor z założonymi rękoma. Nuda. Nosiło mnie moje wewnętrzne ADHD. 30 minut jeszcze dam radę słuchać, ale więcej?! Nie ma mowy! No i jeszcze mógłbym nie usłyszeć Maksyma, kiedy się obudzi i daje znać o tym wszem i wobec!

I tak dzisiaj przypomniałem sobie o tych nagraniach i idąc Lasem Kabackim włączyłem Language Panel o językach programowania. Byłem ciekaw, co też tam Ci myśliciele mówią o językach. Skoro i tak miałem ponad godzinę czasu na spacer, to przecież mogłem go spędzić łącząć przyjemne z pożytecznym.

I tak ze słuchawkami na uszach (głos) i smartfonem w nogach Maksyma (wizja) zeszło mi przyjemnie 40 minut. Las gwarantował spokój, brak zewnętrznych przeszkadzaczy i wiatru, który szalejąc na osiedlu tutaj zanikł kompletnie. Przyjemna sprawa.

Początkowo planowałem godzinny spacer, ale kiedy minęło mi 40 minut, stwierdziłem, że pozwolę sobie na dłuższy spacer i...ponad godzinne nagranie Clojure and the Web. Nie polecam tego nagrania, ale dla napaleńców może być ciekawym podsumowaniem zalet Clojure (przez pierwsze 20 minut) oraz przegląd szkieletów webowych w Clojure z praktycznym przeglądem Ring w drugiej części.

Po 2,5 godzinach wróciłem do domu wyjątkowo zadowolony (!) Maksym przez całą drogę spał smacznie, ja przejrzałem 2 nagrania, co dało nam obu sporą dawkę świeżego (?) powietrza, a reszta rodzinki odetchnęła na jakiś czas od Maksyma. Już nie mogę doczekać się kolejnego spaceru! Co proponujecie do obejrzenia? Może coś w tematyce TDD? Zastanawiam się, czy pomysł odsłuchiwania na mrozie wypali. Ale w końcu i w Norwegii używają Galaxy S2, a tam ciągle zimno.

25 listopada 2011

Wrażenia pokonferencyjne - zacznijmy od JDD w Krakowie

3 komentarzy
Właśnie mija tydzień, w którym miałem przyjemność uczestniczyć w dwóch konferencjach - JDD w Krakowie, w dniach 21-22.11 oraz Eclipse DemoCamp w Poznaniu późnym wieczorem 24.11, żeby nie napisać w nocy.

Obie pozwoliły mi zorientować się w znaczeniu budowania społeczności i konieczności dzielenia się wiedzą. Obawiam się jednak, że to podsumowanie w minimalny tylko sposób będzie odzwierciedleniem moich wrażeń, ochów i echów dla formuły i osób w nich uczestniczących. Klimat obu był wspaniały, aczkolwiek jeden niepodobny do drugiej.

Zacznijmy od JDD 2011...

Do Krakowa zajechałem około 11:00 w poniedziałek. Na hotelu, gdzie odbywała się konferencja, rozwieszono banery konferencyjne (ważna rzecz i do wdrożenia przy kolejnych konferencjach). Wpadłem na Krzyśka Jelskiego, z którym zamieniłem więcej niż trochę słów, aby po kilku kwadransach spotkać Grześka Dudę i Andrzeja Targosza. Później przygotowania do panelu dyskusyjnego ze Sławkiem Sobótką, Andrzejem Grzesikiem i świeżo poznanym Piotrkiem Buckim. Ach, zapomniałbym o Ani Kołodziejczyk. Wybacz Aniu. Na początku rozmowa szła niemrawo, aby, po chwili, przygotowania do panelu przerodziły się w aktywną dyskusję, w której z łatwością można było wskazywać strony, które zajmują rozmówcy. W pewnym momencie wręcz wszyscy "usiedli" na Piotrze. Myliłby się ten, kto pomyślałby, że ciężko jemu było - wyglądało wręcz, jakby większa liczba oponentów tylko go podsycała do dyskusji.

Panel przebiegł...rozmownie. Trochę zabawnie, trochę niemrawo, ale na pewno tłumnie. Sala wypełniona była po brzegi. Czasami dało się odczuć pewne zakłopotanie brakiem aktywności po stronie uczestników, ale zasługą moderatora - Andrzeja Targosza - towarzystwo się rozgrzało i kiedy panel dobiegał końca bez trudu można było zauważyć większe niż przeciętne zaangażowanie wszystkich w dyskusję. Uważam, że ułatwieniem przy pokonywaniu barier publicznego przemawiania było wprowadzenie metody na przedstawienie się, aby w odpowiedzi usłyszeć przedstawienie się rozmówcy i czasami gromki śmiech sali - coś w deseń: "Jak się nazywasz?", na co rozmówca odpowiadał swoim imieniem, np. "Cześć, jestem Maksym", aby po chwili usłyszeć w odpowiedzi "Cześć Maksym, jestem Jacek", co on kwitował "Cześć Jacek!" Coś w ten deseń. Uważam, że te wprowadzające gierki słowne znacząco rozluźniały atmosferę i pomagały rozmówcom. Wiele osób później wyraziły swój zachyt połączony ze zdumieniem, że zorganizowano panel i że interesują nas potrzeby uczestników odnośnie kolejnych edycji konferencji w Polsce. W międzyczasie padało kilka pytań, na które publika proszona była odpowiadać podniesieniem ręki w górę i co najbardziej utkwiło mi w pamięci, to moment, kiedy na pytanie o powód uczestniczenia w konferencji, kiedy padło "Czy poznanie nowego było powodem udziału?" wszyscy, jak jeden mąż, podnieśli do góry rękę. Na naszych twarzach musiało wymalować się ogromne zdziwienie reakcją publiczności. Wcześniejsze pytania kończyły się zwykle kilkoma rękoma w górze, a tu pytanie i...zrobiło się tłoczno w górze. Niezwykłe doświadczenie móc to zobaczyć.

Później obiad, który przeciągnął się przez cały następny wykład, który przegadałem z dopiero co poznanymi osobami.

Na wykład Erika Jan de Wit'a "Scrum – następca modelu kaskadowego" wszedłem z lekkim spóźnieniem. Podobały mi się slajdy, które zwracały uwagę swoją skromnością, a w połączeniu z ostrym światłem projektora, przykuwały oko wyrazistością i dużym kontrastem bieli z odpowiednio dobranym czerwonym (gość pracuje w Canoo, co powinno tłumaczyć dobór kolorów). Muszę wdrożyć ten szablon u siebie w jakieś formie. Dowiedziałem się, że Scrum jest "quick response to change" (co zwykle jednak wiązałem z Kanbanem, o którym za moment, ale teraz sądzę, że to domena każdej z praktyk wytwarzania oprogramowania). Prelegent nie musiał zachęcać do dyskusji i było jej znacznie więcej niż przewidywał. Często wyczuć można było pewne zagubienie we własnych slajdach. 30 minut byłoby jednak bardziej właściwym czasem na to wystąpienie, bo ostatni kwadrans przesiedziałem jak na szpilkach nie mogąc doczekać się końca. Zbyt monotonne i wyłącznie tekstowe prezentacje nie spełniają moich oczekiwań i szybko tracę skupienie.

Kolejny wykład to prezentacyjna porażka. Miałem dosyć po Eriku tego siedzenia i słuchania o Scrumie, kiedy to Paweł Brodziński rozpoczął "Scrum, Kanban i inne opowieści". Pierwsze 15 minut - nic do zarzucenia. Czytam regularnie wpisy Pawła na jego blogu, więc te 15 minut wynikają z dużej dozy zaufania, że cokolwiek nie powie, prezentacja musi być dobra. I w zasadzie była, ale sposób mówienia po angielsku był dobijający. Spokojny ton, prawie senny, z perfekcyjnie dobieranymi i wymawianymi słowami sprawiały, że ledwo dawałem radę utrzymać się na krześle. Paweł dobrze wpasowywał się w kolejne slajdy tak, że nie widać było, czy tak dobrze je zna, czy zerka na nie ukratkiem nie dając tego po sobie poznać. Jako prezenter znający tematykę i przygotowane materiały Paweł dostaje najwyższe noty. Jednak ton przekazania i to chodzenie w kółko - kompletne fiasko. Zbyt wiele gadania, za mało zachęt do angażowania publiki w dyskusję i to oddzielanie każdego słowa. Ledwo wytrwałem do końca. Ucieszyłem się, kiedy padło "Thanks!" Ja jemu też very "Thanks!" i klaskałem bodaj najgłośniej (w końcu koniec!)

Za cel podczas przerw wziąłem sobie poznawanie uczestników. Próbowałem minimalizować rozmowy w grupie, którą znam, aby móc pogadać z nieznajomymi. Tak dowiedziałem się o oczekiwaniach uczestników do wystąpienia Moniki Koniecznej. Kogokolwiek nie zapytałem, wszyscy wskazywali na jej wykład jako kolejny, w który po prostu nie można nie być. Okazało się później, że myliłem Monikę z Patrycją Węgrzynowicz i Holly Cummins. I dobrze, że mnie poprawiono. Jak później z nią rozmawiałem, dowiedziałem się, że nosiła dredy, więc faktycznie mogłem ją pomylić z Holly bez problemu. W ten sposób zrezygnowałem z Andrew Rubingera "Testowanie w środowisku Java Enterprise". Duża interakcja z publiką, gry i zabawy, slajdy w postaci zdjęć z niewielką dawką tekstu sprawiły, że wciągnąłem się. Jednak i tu straciłem cierpliwość, bo ostatnie 15 minut patrzyłem na zegarek, kiedy to lekki merytorycznie temat zaczął mnie nużyć. Monika, co przyznała później w rozmowie, wytraciła poczucie czasu i ostatni kwadrans był bolesną walką z czasem.

Na prezentację Venkata Subramaniama znowu nie dotarłem, bo kolidowała z innymi, ciekawymi (?) wykładami. Z perspektywy żałuję, ale i tak nie odmówiłem sobie zamienić z nim kilku słów na temat prezentacji. Planowałem wręcz zagadnąć go podczas przerw, na co zgodził się z pewnym zachwytem, ale nie dane mi było. Postanowiłem jednak, że po tylu zachwytach publiczności jego wystąpieniami, kolejnym razem obowiązkowo muszę wziąć udział w jednym. Podobnie ze Sławkiem Sobótką. Wszyscy jacyś nawiedzeni z Venkatem i Sławkiem?! Jakieś ogólne pranie mózgu?! Gdzie, kogo by nie zapytać, bez wahania wskazują na ich wystąpienia jako takie, których nie można nie odwiedzić. A ja właśnie pchnąłem się ku temu występkowi. Jakaś mania uwielbienia dla Sławka i Venkata?! Oszaleli, czy co?!

Wieczorem, wspólnie z Jackiem Lisem i Tomkiem zjedliśmy pizzę, aby na 21:00 trafić do klubu na Kazimierzu, w którym odbywała się impreza konferencyjna. Miejsce ciekawe, ale zdecydowanie odradzałbym tam organizowanie pogadanek. Za głośno. Podczas panelu dyskusyjnego padła propozycja, aby omawiać pewne tematy z większą uwagą - ciągła integracja, Scala, NoSQL i środowiska automatycznego budowania. Tematy zostały przypisane do miejsc w klubie i kiedy zobaczyłem salę VIP Room z napisem "Scala", nie miałem złudzeń, które drzwi otworzyć. Niestety, rozmów tam o Scali jak na lekarstwo i jedynym połączeniem między miejscem a Scalą była...nazwa miejsca. Pokój przypominał miejsce schadzek - czerwony, z niedużą leżanką-tapczanem, stacjami z plejakami i dużym telewizorem. Ludzie grali, rozmawiali i widać było, że można było w tym miejscu faktycznie składnie porozmawiać - muzyka nie była tak uciążliwa, jak w innych częściach klubu. Tam przegadałem cały wieczór, aby o północy zwinąć się do hotelu. Pozdrowienia dla studenta z Wrocławia oraz programistek od EJB 2.1 i JBoss 5 z TeleU :-) Bardzo ciekawa rozmowa!

Drugi dzień to "TDD Coding Dojo" z Krzyśkiem Jelskim i Marcinem Zajączkowskim. Dzień wcześniej rozmawiałem z Krzyśkiem, jak będzie przebiegało Dojo i kiedy dowiedziałem się o publicznym programowaniu trochę mnie zmroziło. Przekonanie, że nie jestem gotów do publicznych prezentacji programowania na żywo, jakoś znacząco zaczęło wpływać na moją decyzję, ale ciekawość wzięła górę. Mimo wszystko nie mogłem doczekać się, aby doświadczyć tego na własnej skórze. Niezwykle żywe programowanie w tłumie, gdzie dwie osoby siedząc przed kompem programowało minesweeper'a przy akompaniamencie gapiów z sali. Co 7 minut zmiana jednego "parzysty" i tak do południa. Cudo! Obiecuję sobie więcej tego typu wydarzeń z moim udziałem.

Konferencja pierwsza klasa i życzę każdemu tak owocnych wyjazdów. Nagrodą jest możliwość poznania ludzi z branży i zawsze, ale to zawsze, zwiększenie wiedzy w temacie - niechby nawet niekoniecznie javowym, ale wciąż z obszaru wytwarzania oprogramowania.

17 listopada 2011

Przyszły tydzień konferencyjnie - JDD 2011 w Krakowie i Eclipse DemoCamp w Poznaniu

0 komentarzy
Maksym rozwija się znakomicie. Stuknęło mu 6 tygodni i nie tylko, że zaczął przekręcać głowę z lewa na prawo (z przewagą skierowania na lewo), to zaczął się uśmiechać i reaguje na znajome głosy i zachowania (dorosłych, głównie rodziców, którzy wierzą i brną w zaparte, że te milusie słówka są przyjemniejsze dla ucha malca).


Maksym uśmiecha się, regularnie ogłasza pobudkę około 6:45 (z przewagą godzin wcześniejszych - akurat na ranne bicie dzwonów o 6:30!) i kiedy się złości bardzo intensywnie rusza nogami - najpierw lewą, aby przy udziale prawej być na prawdę zły. Doskonała zabawa to rozpoznawanie jego zachowań - podobne do rozpoznawania działającego oprogramowania bez dokumentacji :)

JDD w Krakowie - 21-22 listopada 2011


Poniedziałek i wtorek jestem w Krakowie na konferencji JDD 2011, w której biorę udział jako uczestnik panelu dyskusyjnego Welcome to Javaland. Za stroną konferencji:
"W czasie konferencji JDD odbędzie się panel dyskusyjny, w trakcie którego zaproszeni goście: Jacek Laskowski, Grzesiek Duda, Andrzej Grzesik, Anna Kołodziejczyk i Andrzej Targosz rozmawiać będą na temat historii rozwoju konferencji i społeczności Java w Polsce. Opowiemy o tym jak doszło do zorganizowania pierwszej imprezy, jak się rozwijały kolejne inicjatywy oraz jaka jest przyszłość spotkań Javy w naszym kraju.

Odpowiemy na pytania dlaczego ważne jest organizowanie w Polsce technicznych konferencji, jak to się stało, ze bez wsparcia jednej mocnej firmy udało się doprowadzić do tak dynamicznego rozrostu społeczności Java w Polsce oraz dlaczego istnienie kilku podobnych eventów równolegle ma sens. Wspólnie zastanowimy się co zrobić, aby zwiększyć ilość uczestników zagranicznych w kolejnych konferencjach oraz co wyróżnia nasze imprezy na mapie Europy."
Trudno mi powiedzieć, czy na miejscu uczestników konferencji cieszyłbym się z takiego "wypełniacza" (szczególnie, że alternatywy nie ma), ale zapytany o udział, od razu się zgodziłem, bo uważam, że wciąż zbyt mało osób udziela się publicznie pro publico bono. Liczę na aktywny udział uczestników konferencji.

Później już w roli uczestnika konferencji zamierzam wziąć udział w prezentacji Tomasza Kowalczewskiego z "Domknięcia w Javie", Erika Jan de Wit'a "Scrum – następca modelu kaskadowego", Pawła Brodzińskiego, którego wpisy na blogu czytam z zapałem, z "Scrum, Kanban i inne opowieści", aby na koniec usiedzieć przy Andrew Rubinger'ze z "Testowanie w środowisku Java Enterprise". Jakoś tak wyszło, że wszystkie z prezentacji będą po angielsku, a tematy są po polsku :)

Drugi dzień chciałbym poświęcić na dokształcanie w temacie TDD z udziałem Krzysztofa Jelskiego i Marcina Zajączkowskiego, którzy poprowadzą "TDD Coding Dojo".

Eclipse DemoCamp w Poznaniu - 24 listopada 2011



W czwartek, 24 listopada, pojawię się wieczorem z tematem "Java EE 6 with WebSphere AS 8 and Rational Application Developer 8" w Poznaniu na Eclipse DemoCamp. Kto jednak chciałby słuchać o Java EE 6, od kiedy stała się wręcz trywialna w użyciu?! Dla wytrwałych będę miał więc niespodziankę w postaci...OSGi Blueprint. Zobaczymy, co WAS8 potrafi uruchomić, a RAD8 stworzyć w tym obszarze. Będzie to dla mnie świetna okazja, aby odświeżyć sobie temat Enterprise OSGi z OSGi Blueprint z Apache Aries w IBM WebSphere Application Server V8.

Zastanawiam się, czy całkowicie zaniechać slajdów na rzecz prezentacji aplikacji, które omówię korzystając z RAD V8 i uruchomię na WAS V8?! Godzina na tego typu cyrki nigdy nie kończy się na godzinie i zostaje tylko niesmak niedopowiedzenia. Przy godzinie uważam, że nie ma co liczyć na wiele, więc pewnie skończy się na slajdach, aby po 45 minutach zachęcić do pytań. Obym nie zapomniał, że moje wystąpienie zaplanowane jest na 9 w nocy!

15 listopada 2011

Enterprise OSGi? OSGi Blueprint? To może Karaf z Aries?

7 komentarzy
Trzeba mi było dyskusji z Łukaszem Dywickim (@ldywicki) na twitterze, abym zrozumiał, jak niewiele trzeba, aby OSGi zrzuciło z siebie czar tajemniczości. Całkowicie. Dzięki Łukasz!

Ostatnio, jeśli mówi się o OSGi to raczej w jego wydaniu korporacyjnym, której celem jest połączenie ze standardami spod sztandaru Java EE, tj. Enterprise OSGi. Pisałem o tym niejednokrotnie na blogu. Niejednokrotnie mówiłem o tym na konferencjach oraz "popełniłem" jeden artykuł w temacie - Enterprise OSGi runtime setup with Apache Aries Blueprint.

Teraz jednak okazuje się, że sprawa jest jeszcze bardziej prosta niż mi się poprzednio wydawało. Nie trzeba specjalnych kwalifikacji do zestawienia środowiska Enterprise OSGi. Wystarczy Apache Karaf i sprawa staje się niezwykle trywialna (jeśli założyć, że nauczenie się jego specyficznych poleceń wpasowuje się w to określenie).

Instalacja Karaf sprowadza się do rozpakowania odpowiedniej dystrybucji. Prościzna.

Uruchamiamy Karaf poleceniem bin/karaf. Są inne sposoby i zainteresowanych odsyłam do "producenta".
jacek:~/apps/karaf
$ ./bin/karaf 
        __ __                  ____      
       / //_/____ __________ _/ __/      
      / ,<  / __ `/ ___/ __ `/ /_        
     / /| |/ /_/ / /  / /_/ / __/        
    /_/ |_|\__,_/_/   \__,_/_/         

  Apache Karaf (2.2.4)

Hit '' for a list of available commands
and '[cmd] --help' for help on a specific command.
Hit '' or 'osgi:shutdown' to shutdown Karaf.
Jak instruuje początkowy ekran, wystarczy skorzystać z tabulacji i/lub polecenia help, aby dowiedzieć się wiele o poszczególnych poleceniach. Dodatkowo, w większości (wszystkich?) przypadków sama nazwa polecenia powinna wyjaśnić przeznaczenie.

Weźmy chociażby polecenie features:list (nie zapominamy o tabulacji po pierwszych literach!)
karaf@root> features:
features:addurl              features:info                features:install             features:list
features:listrepositories    features:listurl             features:listversions        
features:refreshurl          features:removerepository    features:removeurl           features:uninstall
karaf@root> features:list
features:list                features:listrepositories    features:listurl             features:listversions
karaf@root> features:list
State         Version           Name                          Repository             Description
[uninstalled] [2.2.4          ] karaf-framework               karaf-2.2.4            
[uninstalled] [2.5.6.SEC02    ] spring                        karaf-2.2.4            
[uninstalled] [2.5.6.SEC02    ] spring-web                    karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring                        karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-aspects                karaf-2.2.4            
[uninstalled] [1.2.1          ] spring-dm                     karaf-2.2.4            
[uninstalled] [1.2.1          ] spring-dm-web                 karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-instrument             karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-jdbc                   karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-jms                    karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-struts                 karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-test                   karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-orm                    karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-oxm                    karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-tx                     karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-web                    karaf-2.2.4            
[uninstalled] [3.0.6.RELEASE  ] spring-web-portlet            karaf-2.2.4            
[uninstalled] [2.2.4          ] wrapper                       karaf-2.2.4            
[uninstalled] [2.2.4          ] obr                           karaf-2.2.4            
[installed  ] [2.2.4          ] config                        karaf-2.2.4            
[uninstalled] [7.4.5.v20110725] jetty                         karaf-2.2.4            
[uninstalled] [2.2.4          ] http                          karaf-2.2.4            
[uninstalled] [2.2.4          ] war                           karaf-2.2.4            
[uninstalled] [2.2.4          ] kar                           karaf-2.2.4            
[uninstalled] [2.2.4          ] webconsole-base               karaf-2.2.4            
[uninstalled] [2.2.4          ] webconsole                    karaf-2.2.4            
[installed  ] [2.2.4          ] ssh                           karaf-2.2.4            
[installed  ] [2.2.4          ] management                    karaf-2.2.4            
[uninstalled] [2.2.4          ] eventadmin                    karaf-2.2.4            
[uninstalled] [2.2.4          ] jasypt-encryption             karaf-2.2.4            
[uninstalled] [0.3            ] transaction                   karaf-enterprise-2.2.4 OSGi Transaction Manager
[uninstalled] [0.3            ] jpa                           karaf-enterprise-2.2.4 OSGi Persistence Container
[uninstalled] [0.3            ] jndi                          karaf-enterprise-2.2.4 OSGi Service Registry JNDI access
[uninstalled] [0.3            ] application-without-isolation karaf-enterprise-2.2.4
Jak rozumiem istotę features w Karaf to nic innego jak zestawy funkcjonalne - zbiór pakunków, które razem tworzą pewną funkcjonalną całość. Prześwietlmy sam karaf-framework (ponownie nie zapominamy o tabulacji!)
karaf@root> features:
features:addurl              features:info                features:install             features:list
features:listrepositories    features:listurl             features:listversions
features:refreshurl          features:removerepository    features:removeurl           features:uninstall
karaf@root> features:in
features:info       features:install
karaf@root> features:info kar
kar               karaf-framework   
karaf@root> features:info karaf-framework 
Description of karaf-framework 2.2.4 feature
----------------------------------------------------------------
Feature has no configuration
Feature has no configuration files
Feature has no dependencies.
Feature contains followed bundles:
  mvn:org.ops4j.pax.url/pax-url-mvn/1.2.8
  mvn:org.ops4j.pax.url/pax-url-wrap/1.2.8
  mvn:org.ops4j.pax.logging/pax-logging-api/1.6.3
  mvn:org.ops4j.pax.logging/pax-logging-service/1.6.3
  mvn:org.apache.felix/org.apache.felix.configadmin/1.2.8
  mvn:org.apache.felix/org.apache.felix.fileinstall/3.1.10
  mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.asm/3.3_2
  mvn:org.apache.aries/org.apache.aries.util/0.3
  mvn:org.apache.aries.proxy/org.apache.aries.proxy/0.3
  mvn:org.apache.aries.blueprint/org.apache.aries.blueprint/0.3.1
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.console/2.2.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.osgi/2.2.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.log/2.2.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.packages/2.2.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.commands/2.2.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.dev/2.2.4
  mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.config/2.2.4
  mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.modules/2.2.4
  mvn:org.apache.karaf.jaas/org.apache.karaf.jaas.command/2.2.4
  mvn:org.apache.karaf.features/org.apache.karaf.features.core/2.2.4
  mvn:org.apache.karaf.features/org.apache.karaf.features.command/2.2.4
  mvn:org.apache.karaf.features/org.apache.karaf.features.management/2.2.4
  mvn:org.apache.karaf.management/org.apache.karaf.management.server/2.2.4
  mvn:org.apache.aries.jmx/org.apache.aries.jmx/0.3
  mvn:org.apache.aries.jmx/org.apache.aries.jmx.blueprint/0.3
I od razu wiadomo z czego składa się taka kompletna funkcjonalnie całość. Bystre oko dostrzeże tam Apache Aries Blueprint (mvn:org.apache.aries.blueprint/org.apache.aries.blueprint/0.3.1).

Nie pozostaje nic innego jak sprawdzić działanie Aries Blueprint z przykładowym projektem z...Aries Blueprint. Korzystamy z pomocy Karaf, aby zainstalować pakunek z repozytorium mavenowego - wystarczy skorzystać z polecenia install i odpowiedniego adresu z mvn na przodzie.
karaf@root> install -s mvn:org.apache.aries.blueprint/org.apache.aries.blueprint.sample/0.3.1
Bundle start
Bundle ID: 49
karaf@root> ======== Initializing Foo =========
Service registration notification: 5 -1 707063160: Hello FooBar
org.apache.felix.framework.BundleContextImpl@5e6276e5 [a list element, 5] PLN
Fri Apr 17 00:00:00 CEST 2009 {osgi.service.blueprint.compname=foo, key=value}
Działa! I nie trzeba było wiele. Wystarczy Karaf. Spróbuj sam, a przekonasz się, że "zaawansowane" nie musi oznaczać "niedostępne".

Teraz skoro środowisko jest już zestawione, nie ma już wymówek na brak wiedzy do poznania Enterprise OSGi z kontenerem OSGi Blueprint w roli głównej. Jeśli Spring Framework daje Ci wiele radości, to w połączeniu z OSGi może być jej jeszcze więcej.

Czy pracujesz już z Karaf? A może również i Aries albo Spring-DM? Jakie wrażenia? Jest coś ciekawego, co powaliło Cię na kolana? Chętnie wsłuchałbym się w głos praktyka.

12 listopada 2011

Płynny interfejs java.nio.file.attribute.AclEntry.Builder w Java 7

4 komentarzy
Trudno stwierdzić, jak wiele jest tych ciekawostek w Java 7 pod kątem wzorców użytych do rozbudowy API, ale trafiłem dzisiaj na java.nio.file.attribute.AclEntry.Builder, który zbudowany jest w oparciu o warte wzmiankowania konstrukcje programistyczne - wzorzec Budowniczy z tzw. "fluent interface" (często tłumaczone dosłownie jako "płynny interfejs"), czyli techniką konstruowania klas tak, aby metoda zwracała instancję obiektu, dla której została wywołana. W ten sposób możemy wywoływać metody, jedna po drugiej, przez ich łączenie.

Jakkolwiek wątpię, abym często obcował z AclEntry i jej pobratyńcami, to cieszę się, że pojawiła się ta klasa, która uważam, że spopularyzuje ten sposób budowania API w Javie.

Skoro rysunek może zastąpić 1000 słów, to może przykładowy kod z AclEntry.Builder również?
package pl.japila.java7.nio2;

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.attribute.AclEntry;
import java.nio.file.attribute.AclEntryFlag;
import java.nio.file.attribute.AclEntryPermission;
import java.nio.file.attribute.AclEntryType;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.attribute.UserPrincipalLookupService;

public class AclEntryDemo {

     public static void main(String[] args) throws IOException {
          // who...
          UserPrincipalLookupService principalLookupService =
              FileSystems.getDefault().getUserPrincipalLookupService();
          UserPrincipal principal = principalLookupService.lookupPrincipalByName("jacek");
          System.out.printf("Principal: %s %n", principal);
         
          // ...does what.
          AclEntry aclEntry = AclEntry.newBuilder()
                    .setType(AclEntryType.ALLOW)
                    .setPrincipal(principal)
                    .setPermissions(AclEntryPermission.LIST_DIRECTORY)
                    .setFlags(AclEntryFlag.DIRECTORY_INHERIT)
                    .build();
          System.out.printf("ACL Entry: %s %n", aclEntry);
     }

}
Niezłe, co? A to wszystko dostępne w Java 7.

Przy okazji, warto zajrzeć na blog pragmatists.pl, w którym Paweł Lipiński przedstawił temat we wpisie Płynne interfejsy.

Czy ma ktoś pomysły, gdzie użyć AclEntry i jej podobych? A może już jest w użyciu u Ciebie? Jakie zastosowanie? Zachęcam do podzielenia się doświadczeniami, których mi zauważalnie brakuje.

10 listopada 2011

Level 2 Certified IT Specialist decyzją komisji certyfikacyjnej IBM CEE/MEA

2 komentarzy
Panie i Panowie, Ci mali i Ci duzi, Ci mniej i Ci bardziej doświadczeni, i tak dalej, i tym podobne.

Właśnie otrzymałem od komisji certyfikacyjnej w IBM mail następującej treści:

"Decision of the CEE/MEA IT Specialist Level 2 Certification Board

Dear Jacek

It is my pleasure to inform you about the positive decision of the CEE/MEA IT Specialist Certification board who is herewith approving your IT Specialist Level 2 Certification.
You may now use the title Level 2 Certified IT Specialist. This title is independent of your position (i.e.band) and indicates that you are certified in the IT Specialist profession.

I wish you much success in your professional career in the future.

Best regards

Franziska Feller
IT Specialist Profession Leader Northeast IOT & CEE/MEA
IT Architect Profession Leader CEE/MEA & ALPS"


Tłumacząc na polski - z dniem dzisiejszym przechodzę na wyższy level zgodnie ze ścieżką rozwoju profesjonalnego w IBM.

Założeniem programu certyfikacyjnego jest uhonorowanie dążeń pracowników IBM do profesjonalnego wykonywania zadań w duchu poszanowania zasad etyki zawodowej. Brzmi trochę wyniośle i może aż nadto patetycznie, ale w założeniu ma prowadzić do wyróżnienia osób, którym nie trzeba mówić, a które mówią i którym nie trzeba pokazywać, a które pokazują. W pakiecie kandydat opisuje, dlaczego jego udział w projekcie miał wpływ na niego (projekt nie kandydata). Mimo, że przez długi czas bojkotowałem ten proces (trochę ukrywając przy tym swoją obawę o brak kwalifikacji), aby ostatecznie ulec zachętom.

12 września 2011 wysłałem pakiet - dokument podsumowujący moją działalność przez ostatnie 5 lat, co pozwoliłem sobie na upublicznienie we wpisie Pakiet certyfikacyjny na specjalistę IT wysłany. Do zebrania komisji dzieliły mnie 3 wywiady z innymi IBMerami, którzy takie miano już posiadają - 2 polaków i jedna osoba z RPA. Oni to podczas komisji certyfikacyjnej uchwalają "zdatność" kandydata do przyjęcia tytułu. W moim przypadku odbyło się zgodnie z moimi oczekiwaniami! Pamiętam jednak, że wywiady (swego rodzaju rozmowy kwalifikacyjne) nie były dla mnie lekkie. Miałem nieodparte wrażenie, że ogólne postrzeganie jest takie, że za mało w nim konkretnych zasług projektowych, które mogłyby uzasadniać moje aspiracje. Nie chodziło o podparcie ich certyfikatami produktowymi czy po prostu wykonywaniem swoich obowiązków, ale nietuzinkowymi "zagraniami", które mogłyby wyróżniać mnie z tłumu. Okazało się jednak, że było w tym pakiecie wystarczająco wiele, aby się obronił i pozwolił mi na dzisiejsze świętowanie.

Jest to swego rodzaju podsumowanie mojej pięcioletniej działalności w IBM i jestem niezwykle dumny móc pochwalić się tytułem. Od tej pory jestem jego orędownikiem :)

Więcej o programie certyfikacyjnym na stronie Welcome to the Open CITS Certification web site.

08 listopada 2011

Eclipse DemoCamp 2011 w Warszawie innymi słowy

9 komentarzy
2 tygodnie temu...świeżo po warsjawie 2011.

Pada pomysł zorganizowania Eclipse DemoCamp (EDC) 2011 w Warszawie. Były urodziny Eclipse, pojawiła się Java 7, jest potrzeba zorganizowania inauguracyjnego spotkania Warszawa JUG - robimy EDC. Nagłaśniam temat na forum WJUGa. Zgłaszają się prelegenci - Piotr Chmielewski z JavaFX, Paweł Cesar Sanjuan Szklarz z G1 i ja z java.util.concurrent w Java 7.

Jakoś tak w tym samym czasie...

Kontaktuje się ze mną firma mLife. Chcą wejść we współpracę z grupą WJUG. Świetnie się składa, myślę. Proponuję udział w sponsorowaniu EDC. Przyjmują. Mam kaskę na pizzę. Na napoje również. Mam wszystko! Jestem Panem wszechświata. Ponosi mnie.

Rozpoczynam rejestrację. Czekam na poniedziałek, aby wyliczyć zamówienie pizz. Wychodzi 80 zarejestrowanych. Piszę do pizzerii - Da Grasso. Podobno nieciekawy wybór, ale co mi tam - pizza to pizza. Nie mam do tego głowy.

Dzwonię do pizzerni. Szast, prast i mam zamówienie. Gość współpracował z nami, więc wie co w trawie piszczy. Poszło gładko. Temat z głowy. No prawie. Jeszcze tylko sprawdzę, czy wszystko w porządku z płatnością i dostawą, ale to już we wtorek.

Siedzę w java.util.concurrent. Przygotowuję prezentację. Zaczynam zastanawiać się, czy ja aby jestem dobrze przygotowany do tego przedstawienia?! Mam wątpliwości, czy temat zajmie jedynie 30 minut. Będę musiał gonić. Nie lubię tego.

Nadchodzi wtorek, 8.11. To już dziś! Mam prezentację, mam pizzę, mam prelegentów. Jest wszystko! Jeszcze ostatnie szlify mojej prezentacji, jeszcze polerka o Phaser i wybija 16:30. Pora się zwijać na Banacha.

17:05. Wjeżdza 504. Jadę.

Momento! Czy ja aby zamówiłem również napoje?! Dzwonię do pizzerii. "Czy w zamówieniu są napoje?" pytam. Po drugiej stronie spokojnym głosem "Nie". CO?!?! O w mordę! Proszę o zmianę - tniemy pizze. Ile napoi? Jakie? Cola? Mają tylko 1L. Wybieram Tymbarka 0,25. Ma zrobić, aby było dobrze. Lubię dobrze i gość wie, co jest grane. Zdaję się na pomoc z pizzerii. Uff, dobrze, że w ogóle o tym pomyślałem! Załatwione.

17:59. Rozpoczynamy. Widzę znajome twarze. Dużo tych twarzy. Różne płcie. Jest też mLife i zaczyna się rozdawanie gadżetów. Fajnie, że jest ich tylu. Gdybym miał to przygotowywać samemu - odleciałbym. A tak, fajna kobitka jest i w ogóle jakoś tak poukładane wygląda.

Przygotowuję kamerę.

Pierwszy prelegent stremowany niemiłosiernie. Prosi o zwłokę. Może 10 minut krócej. CO?! Koleś, zluzuj, to przyjazna klientela. Zaczynam myśleć, że koleś zejdzie mi na serce. Jakby mu pomóc? Słownie poklepuję go po ramieniu. Daje radę. W końcu wchodzi na scenę. Kamera, akcja! Cicho, za cicho mówi. Bawię się kamerą, aby nagrać jak Piotr występuje w roli prelegenta. Widać tremę. Co?! Przeprasza za nią?! Oj, gościu, tego się nie robi. To widać, więc po co o tym jeszcze mówić?! Mów o JavaFX! Trema robi swoje. Koniec wystąpienia. Oklaski. Widać dumę u Piotra. Brawo! Pora na drugiego prelegenta.

Drugiego?! Kurcze, gdzie jest Paweł? Paweł, gdzie jesteś. Nie ma go na sali. Chwila zastanowienia i po moim pytaniu o możliwość wystąpienia publika akceptuje plan awaryjny. Rozkładam się, a tu dzwoni dostawca z pizzerni. Jest pizza! Zatem przerwa. Wchodzi Paweł. Co za bieg wypadków. Nie za szybko aby? Zaraz zejdę na serce. Uff, na przerwie sobie odsapnę.

Pizza-time. Robię za kelnera. Pada z tłumu "Przydałoby się trochę sosu". Nie ma sosu?! Tutaj jest! Rozdaję zainteresowanym, ale teraz dopiero reflektuję się, że obsługuję jedynie lewą stronę. Prawa daje sobie radę widzę. Jest dobrze. Pizza schodzi i napoje również. Auć, napoi już nie ma, a pizza jeszcze jest! Cóż, przy następnym razie pomyślimy i o tym. Zapisane na stronie "Do poprawy". Czas retrospekcji już się zaczął (mimo, że impreza wciąż trwa).

Podchodzi Marcin, a może Maciej? Kurcze, już nie pamiętam. Proponuje robótkę. Firma z Gdańska dała ciała i nie dokończyła serwisu. Jest finansowanie, ale nie ma komu robić?! Co za czasy - robota sama przychodzi. Pytam "Jak nas znalazł". Google i takie tam. Przyszedł, aby zaproponować pracę z Grails. Wygląda ciekawie. Muszę się zastanowić. Nie mam do tego głowy teraz. Obiecuję nagłośnić temat przed kolejnym wystąpieniem, na blogu i grupie. Zawsze marzyłem o zbliżeniu inwestorów do naszej grupy. Czyżby marzenia się spełniały?!

Pora przygotować się do prezentacji. Godzina 18:57. Jestem gotów, a tu pada "Może jednak moglibyśmy utrzymać harmonogram? Wolałbym, aby Paweł teraz wystąpił." Ups. Chyba mnie tu nie lubią. Idę ustalić temat z Pawłem. Jest zgoda. Paweł się rozkłada. Ja na scenie wyłuszczam temat z Gdańska. Cisza na sali. Pospali się?! Chrapaliby chyba, co? Nie. Wszyscy patrzą na mnie. Chyba słuchają.

Paweł wchodzi na scenę. Akcja!

Dostaję informację, że przyjechała druga partia pizz. I tyle widziałem Pawła. Przyjechało bodajże 10 nowych - 3 rodzaje. Zaczynam rozmowę na korytarzu o możliwościach ożywienia studentów z MIMUWu z p. dr Jabłonowskim. Pizza schodzi. Jacyś "przechodnie" pytają o możliwość uszczknięcia pizzy. A proszę bardzo. "A z jakiej to okazji?" pada. "Mamy spotkanie javowe" - odpowiadam.

Godzina 19:25. Wchodzę do sali. Paweł w najlepsze opowiada o G1. Widać zainteresowanie publiczności. Padają pytania, Paweł oddaje się rozważaniom, widać interakcję. Jest dobrze. Momento, ale czy nie powinien już kończyć?! 19:30. On wciąż przy mikrofonie i nie widać końca. Pokazuję, że koniec. Paweł widzi, ale brnie w zaparte. "Uparty gość" myślę sobie. Cóż, niech ma jeszcze 5 minut. 19:35. Wciąż mówi. Bach, jest ostatni slajd. Będzie koniec. Jest!

Wspominam o pizzy. Daję 5 minut na przerwę i zapraszam na przekąskę, toaletę i w ogóle odświeżenie umysłu. Już przeczuwam, że ze mną będzie bolało. Mam 30 slajdów, 30 minut i godzinę prawie 19:45. Nie jest dobrze.

Zaczynam. Idzie 1 slajd, później drugi. Widać, że ludzi mniej niż na poprzednich wystąpieniach, ale zrzucam to w duchu na późną porę. Na pewno nie na mój temat, czy mnie samego. Niemożliwe!

Rozgrzewam się. Idzie coraz sprawniej, padają pierwsze pytania. Już nie pamiętam, czy sam nie prowokuję ich. Czas płynie, a ja w połowie. Kolejne pytania, tym razem moje. Pada odpowiedź, druga, wywiązuje się dłuższa wypowiedź. Nie nie mogę na to pozwolić. Muszę skracać. Zaczynam biec. Auć, chyba za dużo przygotowałem do omówienia. A miało być za mało na 30 minut!

Jest 20:15, może 20:20. Pytam, czy mogę prosić o 15 minut dłużej. Pada, że nawet mam 20. Jest lepiej. Koniec o Fork/Join. Nie ma przykładów. Za mało czasu. Muszę nadganiać.

Wchodzimy w ThreadLocalRandom. Tutaj krótko - 1 slajd. Zapominam o tym i przerzucam na kolejny, a tu...Phaser. A właśnie, miało być o Phaser! Szybko przypominam sobie, co tam miałem powiedzieć. Wspominam o książce i głęboki oddech. To będzie z górki. Chyba polubiłem Phaser. Jakiś taki prosty się teraz wydaje. Nadrabiam trochę miną, pomaga mi publika. Jest dobrze. Prezentacja się klei. Tak lubię!

Jest godzina 20:30. Nie! Jest później! 20:45. Znowu zawaliłem z czasem. Trzeba nie było prowokować publiki do dyskusji. Trzeba było trzymać się planu, a nie improwizować jak na "jam session". Następnym razem. Następnym razem.

Jeszcze na koniec prezentacja aplikacji z sourceforge. Chyba się podoba. Sala wybucha gromkim śmiechem. Jest dobrze. Publika się bawi, ja wciąż na scenie - dam radę. No nie, chwila przed 21:00. Zdecydowanie za późno skończyliśmy. Następnym razem będę pilniejszy. 30 minut to trochę mało. Koniec. Oklaski.

Ale co jest?! Pochodzi gość i proponuje wystąpienie na...5 minut. Co?! Nietechniczna publika?! O czym będę mówił?! O prowadzeniu bloga, WJUGa, prezentacje publiczne. Cokolwiek. "Trzymaj się 5 minut!" pada. Nigdy nie brałem udziału w takim przedsięwzięciu. Biorę to! Będzie jazda, ooostra jazda.

Dyskusje, pożegnania, złożenie spotkania. Chyba się udało. Oby nie dostrzegli tych ostrych kantów. To EDC to jeden wielki kant. Jestem zadowolony ogólnie. Samemu udało mi się zestawić to spotkanie. Widać nie wypadłem z wprawy. Ktoś musi mi trochę posłodzić?! Kolejnym razem muszę kogoś zaprosić. Samemu to przewalić się można.

Na zegarze 21:15. W domu jestem po 22. Dzieciaki okupują łazienkę, żonka i dzidzia śpią. Publikuję prezentację z mojego wystąpienia. Nie mogę nie prosić o słowa krytyki. Muszę wiedzieć, gdzie miałem wpadkę. Lubię doskonalić warsztat. Łudzę się, że ktoś jeszcze zechce do nich zajrzeć.

Wciąż ślęczę nad tym wpisem. O łazienka wolna. Koniec. Idę spać. Paaaa.