niedziela, 25 września 2011

Połączenie Androida z lokalnym servletem


Ostatnio miałem za zadanie skomunikować Androida z własnoręcznie napisanym serwletem. Przykładów w necie można znaleźć pełno, jak się prosto połączyć z Internetem i ściągnąć dowolny dokument czy grafikę. Jest to prosta rzecz o ile pamiętamy o kilku sprawach.

Po pierwsze to należy zmodyfikować nieco plik AndroidMainfest.xml dodając następujący wpis:

<uses-permission android:name="android.permission.INTERNET"/>

Teraz już kod odpowiedzialny za połączone z Internetem powinien już działać. Nie będę go prezentował, bez problemów znajdziecie. Ja tymczasem chciałem się połączyć z własnym Serwletem (osadzonym na Tomcat’cie), uruchomionym na tym samym komputerze co emulator telefonu. No i tutaj zaczęły się schody.

Pierwszy pomysł jaki przychodzi do głowy, to magiczny adres IP: 127.0.0.1. Niestety dla emulatora i telefonu oznacza to tą samą maszynę, czyli emulator / telefon. Po krótkim namyśle skorzystałem z adresu IP mojego komputera. Działa, ale nie byłem z tego zadowolony, gdyż w tym momencie stawało się to nietestowalne, w przypadku uruchomienia na innej maszynie.

Próbowałem również skorzystać z adresu IP routera, który dzieli mi Internet w mieszkaniu. Niby już się tam cos łączył, ale timeout leciał. Prawdopodobnie coś źle skonfigurowałem. Szukając po komunikatach wyjątków, w końcu natrafiłem na super rozwiązanie (niestety piszą ten post nie mogę odnaleźć źródła), na które w życiu bym sam nie wpadł.

Chcąc się połączyć z emulatora Androida na komputer na którym obecnie jest ten emulator uruchomiony, należy skorzystać z IP: 10.0.2.2. Dzięki temu łatwiej odpalić aplikację na innym komputerze. Zastosowanie tego adresu, powoduje że po stronie serwera, będziemy widzieć nasze żądania jako pochodzące z 127.0.0.1. Natomiast żądania wysyłane na adres IP naszego serwera, będą miały źródło takie samo, na którym stoi serwer.

Życzę więc miłego kodowania i bezproblemowych połączeń między emulatorem a testowym serwisem. Mi dojście do tego zjadło sporo czasu.

środa, 15 czerwca 2011

Confitura pełna wiedzy – wrażenia po konferencji

W sobotę 11 czerwca odbyła się w Warszawie największa darmowa konferencja javowa w Polsce: Confitura, zwana wcześniej Javarsovią. Na początku wielkie podziękowania dla organizatorów, wolontariuszy i sponsorów, za chęć organizacji i wsparcia tejże inicjatywy. Ale od początku.

Do Warszawy przybyłem w piątek wieczorem, aby być wypoczętym na konferencji. W sobotę byłem na miejscu o 8.30, szybka rejestracja, obchód po stanowiskach sponsorskich, spotkanie znajomych…

O 9.15 członkowie kapituły oficjalnie rozpoczęli Javarsovie Confiturę. Pierwszy wykładzik był sponsorski na temat KeyNote. Prowadzący mówił bardzo cicho i monotonnym głosem, no ale płaci to niech ma :P Był to dobry czas na rozwiązanie konkursów, przygotowanych przez sponsorów. Pod koniec już wyszedłem i chciałem się napić czegoś. Niestety obsługa cateringowa stała, ale napoje czekały dopiero na przerwę kawową co mnie się niezbyt spodobało.

W tym roku zestaw uczestnika był troszkę uboższy niż rok wcześniej. Zamiast materiałowej i ekologicznej torby (używam do dziś) była papierowa i brakowało mi notesika (na szczęście się przed tym zabezpieczyłem). Nie ma jednak na co narzekać, gdyż konferencja jest w pełni bezpłatna i nie można wymagać nie wiadomo jakich gadżetów. Nie to jest najważniejsze, gdyż nie po gratisy przyjechałem.

O 10.35 zaczęły się pierwsze wykłady. Ja się udałem na Aspekt bezpieczeństwa w tworzeniu aplikacji internetowych Jakuba Koperwasa. Prelegent zaprezentował popularne ataki na aplikacje webowe (jak SQL Injection) jak i mniej popularne (jak CSRF). Wspomniał on również o inicjatywie OSWAP, dzięki której można się pobawić w hakowanie.

Było też o sposobach, jak można się bronić przed różnymi atakami. Przede wszystkim należy nie przestawać myśleć i nie ufać ślepo framework’om. Powinniśmy walidować dane, a nie formularz, gdyż dane do naszej aplikacji mogą spływać różnymi drogami – nie tylko poprzez żądanie http, ale także z innych serwisów, aplikacji, z telefonów... W celu walidacji danych może nam pomóc BeanValidation JSR-303, za pomocą którego można zdefiniować, jakie ograniczenia powinny mieć nasze dane.

Warto również znać różnice pomiędzy używanymi framework’ami i bibliotekami, Przykładowo GWT traktuje tekst jako zwykły tekst, natomiast ExtGWT, jako html. Dzięki temu tworząc przycisk z tekstem <b> text </b> w tym pierwszym dokładnie taki napis zobaczymy na ekranie, a w przypadku ExtGWT dostaniemy przycisk z pogrubionym tekstem.

Kolejnym rodzajem omawianego ataku była kradzież sesji. Można się przed tym bronić, dodając do każdej akcji jednorazowy RequestId, który jest później unieważniany. Można z palca to naklepać, lub jeśli korzystamy z Seam’a, wykorzystać znacznik <s:token>. Można również monitorować czy na pewno uprawniony użytkownik korzysta z danego klucza sesji. Można dodatkowo monitorować MAC i IP, a także używaną przeglądarkę. O ile IP może się czasem zmienić (zależy jakiego mamy dostawcę Internetu), to już zmiana przeglądarki może być podejrzana. Wszystko również zależy od krytyczności naszej aplikacji. Jak by się trzeba było co kilka minut logować na facebook’a, to by ludzie przestali się z niego korzystać. Również warto przesyłać ciasteczka po https. Prelegent na koniec polecał przeczytanie 12 rules for developing more secure Java Code.

Prelegent opowiadał jeszcze o kilku ciekawych rzeczach. Przekazał w ten sposób sporo wiedzy słuchaczom. Może trochę mi brakowało przykładów, ale przy takim czasie prezentacji ciężko je zaprezentować. No i nie było czasu na dogłębne analizowanie omawianych problemów. Prelegent mówił szybko, ale zrozumiale i nie dało się spać. Wykład mi się podobał.

Później była przerwa kawowa. Następnie chciałem iść na Tomasza Skutnika i prezentację: Gdzie jest moja tabela? Czyli jak sobie radzić w Javie i SQL gdy zmienia się schemat bazy danych. Kolega Szymon mnie jednak odwiódł od tego zamiaru i wylądowaliśmy na prezentacji Patrycji Węgrzynowicz, pt. Patterns and Anti-Patterns in Hibernate. Patrycja już kilka krotnie występowała z tą prezentacją na innych konferencjach, w tym na 33deegre i GeeCon’ie. Nawet slajdy zawierały na końcu informacje o pierwszej z wymienionych konferencji.

Prelegentka wzięła na warsztat przykładowa aplikację CaveatEmptor z książki Java Persistence with Hibernate – biblii do Hibernate’a napisanej przez jej twórców. Pokazując kawałek kodu, Patrycja pytała publiczność, czy wiedzą, gdzie jest błąd. Znalazł się ktoś z sali, kto dobrze trafił, co się nie zdarzało na poprzednich wystąpieniach. Jak się okazało, nawet twórcy Hibernate’a mogą się czasem pomylić w pracy ze swoim narzędziem. Z ciekawszych rzeczy, co zapamiętałem, to użycie metody Collections.unmodifableList(), która zwraca jedynie wrappera na oryginalną kolekcję. I w zależności od implementacji getterów i setterów, możemy sobie coś zepsuć. Wykład całkiem, całkiem, tylko te częste eeee… i yyyyyy… Patrycji powodowały, że już się go tak przyjemnie nie słuchało.

Kolejnym wykładem na jaki się udałem, to Jak wycisnąć maksimum z testów? Bartka Majsaka. Było trochę o testach integracyjnych i akceptacyjnych. Prelegent wspominał o takich rozwiązaniach jak Tumbler (wspomaga pisanie w stylu BDD) Cargo (wspomaga konfiguracją i deploy'em w różnych kontenerach) i Arquillian (do testowania kodu osadzonego w kontenerze). Praktyczny przykład z tym ostatnim nie zadziałał, prawdopodobnie z powodu problemów z netem.

Dalej było o Selenium / WebDriver. Bartek testował za jego pomocą funkcjonalność na github'ie. Mianowicie po wciśnięciu T, można wyszukiwać pliki z danego projektu. Istnieje również możliwość eksportu z Selenium do JUnit’a 4, ale to się i tak nie kompiluje i w ogóle nie działa. Można to jednak poprawić (tudzież ręcznie napisać) i wtedy można uruchamiać testy bezpośrednio z ulubionego IDE.

Było jeszcze trochę o BDD i jak można ładnie DSL’e w Groovy’m wykorzystać. Warto również w trakcie build'ów z maszyn wirtualnych korzystać, jeśli musimy przeprowadzać testy w zróżnicowanych środowiskach uruchomieniowych. Prelegent próbował jeszcze coś tam pokazać, za znów nie zadziałało z winy sieci. Spodobała mi się idea nagrywania screencast'ów z testów akceptacyjnych, które to później można wykorzystać, do zbudowania prezentacji pokazującej funkcjonalność produktu.

Następnie był obiad. Tym razem trzeba było sobie za niego zapłacić (nie było tak fajnie jak rok temu) a i tak jakiś wypaśny nie był: zupka, sałatka, kanapka i jabłko. Później był wykład sponsorski, czyli jak zwykle…

Następnie udałem się na Re-fuck-toryzacja czyli sprowadzanie sp****go kodu na właściwe tory Pawła Lipińskiego. Chciał on swoim wystąpieniem udowodnić, że jeszcze potrafi programować… W trakcie prezentacji było krótkie ogłoszenie od organizatorów, że właśnie odholowują źle zaparkowane samochody. Ktoś wybiegł z sali...

Paweł wziął pod lupę open source’owy projekt e-commerce OFBiz Pokazywał w jaki sposób przeprowadzać bezpieczne refaktoryzacje. Da się, nawet bez posiadania testów. Nie odpalał jednak na końcu aplikacji, więc nie wiadomo czy wyszło:P

Trochę czasu zabrakło na pokazanie wszystkiego, a im dalej, tym ciężej było śledzić co się dzieje w kodzie. Na koniec był jeszcze zabawna piosenka o refaktoryzacji przygotowana przez autora.

Kolejną prezentacją, na której byłem, było Zastosowanie przetwarzania asynchronicznego w aplikacjach Tomka Łabuza. Testował on obciążenie aplikacji i pokazywał, jak się ona zachowuje przy przetwarzaniu synchronicznym jaki i asynchronicznym. Prelegent mówił również, kiedy warto zastosować takie rozwiązanie w naszej aplikacji.

Następnie była przerwa kawowa i losowanie nagród od sponsorów. Ja wygrałem otwieracz do piwa z funkcją pendrive’a i 2 bilety do kina. Tak więc można powiedzieć, że losowanie nie było ustawione, ale i tak wolałbym Xbox’a :P

Ostatnią prezentacją w której miałem możliwość uczestnictwa było: Pisz po pijaku, przeglądaj na trzeźwo Piotra Przybylaka. Tu również były nagrody dla aktywnych uczestników, tylko że w postaci piwa lub gorzkiej żołądkowej. W końcu tytuł prezentacji zobowiązuje :)

Prezentacja była o sposobie, w jaki działa nasz mózg i czy da się to jakoś wykorzystać. Można się przełączać pomiędzy rożnymi trybami jego pracy, np. za pomocą alkoholu, spaceru, pisaniu czegoś na kartce zaraz po przebudzeniu… Chcąc wykorzystać dwa tryby pracy mózgu, można stosować pair programing, gdyż wtedy kierowca skupia się na pisaniu linijek kodu, a pilot o tym nie myśli, ale ma za to obraz całości.

Dobre może być również odwrócenie problemu. Chcesz się nauczyć pisać dobry kod? Napisz jak najbardziej brzydki, zagmatwany i niezrozumiały kod. Prelegent wspominał jeszcze o modelu kompetencji braci Dreyfus, Shu Ha Ri, kryzysie pielęgniarek w stanach i o powstawaniu nowych neuronów w mózgu. Podobno szczurom w warunkach laboratoryjnych nowe neurony się nie rodzą (no bo i po co?), ale kto wie jak to w rzeczywistości jest...

Generalnie na wykładzie było sporo śmiechu i sporo braw. Było lekko i przyjemnie. Idealny wykład na końcówkę konferencji. Brawo.

Później było tylko zakończenie konferencji. Podziękowania dla organizatorów, wolontariuszy i sponsorów. Było jeszcze losowanie przygotowanych nagród, ale już na nic się nie załapałem. Liczba osób, które potwierdziły rejestracje to 742, ale wiadomo – ktoś jeszcze nie dojechał, ktoś jeszcze doszedł, wiec trochę ciężko przybliżyć rzeczywistą liczbę uczestników.

Po confiturze udałem się jeszcze pod PKiN na piwko z Szymonem. Ja jeszcze zostałem na niedziele w Warszawie. Wracając pociągiem rozwiązywałem jeszcze jedno zadanie konkursowe firmy OutBox. Musze przyznać, ze bardzo ciekawy konkurs (tzn. treść tego co trzeba zrobić, a właściwie gdzie ją znaleźć). We wtorek było ogłoszenie wyników, ale niestety nic nie wygrałem.

Podsumowując konferencję, to wypadła ona trochę słabiej od zeszłorocznej edycji. Wydaje mi się, że wcześniej wykłady były na trochę wyższym poziomie (albo to ja się czegoś w ciągu roku nauczyłem). Było ciężko się przemieszczać pomiędzy salami (co nie jest dziwne przy tej liczbie uczestników), co skutkowało spóźnieniami na prelekcje. Przerwy mogły by być trochę dłuższe, a napoje dostępne non stop. Więcej niedociągnięć się nie dopatrzyłem i za rok będę starał się znów wziąć udział w tej konferencji.

wtorek, 7 czerwca 2011

Zmiana nazwy pakietu w projekcie Android'owym w IDEA

W jednym z ostatnich wpisów: Inne podejście do przechowywania danych w systemie Android, z wykorzystaniem db4o i NetBeans 6.9 wspominałem o użyciu IntelliJ IDEA w celu sprawdzenia jak sobie radzi z aplikacjami android’owymi. I rzeczywiście wsparcie jest lepsze. Póki co to natrafiłem tylko na dziwne zachowanie jeśli chodzi o zmianę nazwy pakietu. Mianowicie po wybraniu pakietu i Refactor -> Rename (Shift + F6) wyskakuje mi poniższy monit:



Z początku trochę mnie zdziwił komunikat. Patrząc tylko na przedostatnią linię, nie rozumiałem intencji. Przecież pakiet jest utożsamiany z katalogiem, więc o co chodzi? Bliższe wczytanie się w komunikat, już wyjaśnia co się dzieje. Otóż IDEA umieszcza pliki automatycznie generowane (takie jak klasa R) w osobnym katalogu (/gen). Niezależnie od wybranej opcji (po za Cancel oczywiście) zmieniana jest nazwa katalogu zawierającego nasze pliki źródłowe. Przy wyborze Rename package, dodatkowo zostanie zmieniona nazwa podkatalogu /gen, gdzie są generowane automatycznie pliki projektu (np. klasa R).

Teraz przy próbie uruchomienia (Shift + F10) aplikacji wyskakuje okienko do edycji konfiguracji.



Możemy w tym momencie olać ten ekran i samemu poprawić ścieżki do naszych aktywności w pliku AndroidManifest.xml. Całe szczęście, że IDEA podświetla na czerwono błędne klasy, umieszczone w plikach XML-owych. O takiej funkcjonalności w NetBeans’ie można tylko pomarzyć.

Kilkakrotne próby powtórzenia tej czynności, uświadomiły mi, że środowisko nie zawsze tak samo wszystko modyfikuje. Raz musiałem w jakimś pliku konfiguracyjnym coś grzebać, a ostatnio nawet udało się odpalić od razu aplikację. Czyżby to było adaptacyjne środowisko programistyczne? Jeśli tak to jestem pod wrażeniem.

sobota, 28 maja 2011

Podświetlanie wystąpień zmiennych w kodzie w Eclipse

Jakiś czas temu mój Eclipse zwariował i nie chciał podświetlać wszystkich wystąpień zmiennych w kodzie Javy, gdy na jakiejś zmiennej był ustawiony kursor. Moja praca stała się bardziej uciążliwa, gdyż trudniej mi było przeczytać / zrozumieć nie swój kod.

Jako że nie znam dokładnie środowiska, chwilę się naszukałem co może być nie tak. Wszystko można zmienić w menu Window -> Preferences -> Java -> Editor -> Mark Occurrences.



Warto mieć tu wszystko włączone, aby widzieć co gdzie w kodzie występuje. Przykład poniżej:



Kursora bezpośrednio nie widać, ale proszę mi wierzyć, że jest on ustawiony na obiekt separator w linii 14. Dzięki temu w linii 16 widzimy podświetlenie tej samej zmiennej.

Podsumowując powiem jeszcze, ze pisząc ten post zrozumiałem, dlaczego w pewnym momencie to podświetlanie mi zniknęło. Otóż chcą sobie przypomnieć skrót klawiaturowy do wyświetlania Outline’a aktualnej klasy w oknie z kodem, omyłkowo wcisnąłem Alt + Shift + O, co jak się okazało wyłącza podświetlanie tych zmiennych. Natomiast skrót do wyświetlania Outline’a klasy (czyli zawartości) to Ctrl + O. Podwójne wciśnięcie tej kombinacji, to wyświetlenie całej zawartości klasy, wraz z klasami bazowymi.

Tyle na dziś.

Żródło:
Eclipse: Mark Occurrences for Quick Visual Help

poniedziałek, 16 maja 2011

Wrażenia po konferencji GeeCON cz.2 (Conference Day II i Community Day)

Wrażenia z pierwszego dnia konferencji opisałem już w poprzednim wpisie: Wrażenia po konferencji GeeCON: Conference Day I. W piątek (Conference Day II) jakoś ciężko mi było się wcześnie rano zebrać. Jako że znów początkowo musiałem być na stoisku firmowym, nie uczestniczyłem w porannych wykładach.

Pierwszy wykład na który dotarłem to była prelekcja: Eugene’a Ciurana The No-Nonsense Guide to Hadoop and HBase in Enterprise Apps. Autor opowiadał o framework’u Hadoop, który skupia w sobie sporo innych ciekawych technologii, wspomagających rozproszenie systemu. Było dużo wiadomości, ale bez konkretów. Trochę dokładniej było o bazie HBase podobnej do BigTable od Google. Na koniec prelegent namawiał do pracy w swojej firmie i sporo oferował, za polecenie pracownika.

Później był obiad, dokładnie taki jak wczoraj. Część uczestników zamiast niego poszła gdzieś indziej zjeść.

Następnie udałem się na prezentację Marka Matczaka pt. 10 common pitfalls when using Hibernate, z którym mam przyjemność współpracować. Słyszałem również tą prezentację kilka dni wcześniej i dokładnie wiedziałem o czym będzie. Marek pokazał pułapki na jakie można się natknąć używając Hibernate’a. Ciekawa prezentacja poparta przykładami z życia. Po prelekcji grupka ludzi otoczyła Marka, zasypując go pytaniami. Sporo ludzi nie zrozumiało idei session-per-conversation, czyli wzorca przydającego się w aplikacjach, gdzie mamy kilka kroków w jakimś procesie, jak np. bookowanie biletów lotniczych. Warto wówczas zacząć sesję Hibernate’ową na początku procesu rezerwacji biletu, a zakończyć ją, gdy już będzie zapłacone. Rozwiązanie takie jest zaimplementowane we framework'u Seam.

Następnie poszedłem na Anton’a Arhipov’a Bytecode for discriminating developers. Początkowo było o drzewach AST, czyli krótkie wprowadzenie do kompilatorów. Muszę przyznać że slajdy były bardzo ładnie przygotowane, zwłaszcza te pokazujące operacje wykonujące się na stosie. W ogólności jest 256 słów kluczowych w maszynie wirtualnej Javy, i praca z bytecode’m nie jest taka straszna dzięki narzędziom javap (do podejrzenia kodu JVM) i Javassist (do modyfikowania kodu w locie). Później trochę przysnąłem i obudziłem się pod koniec. Anton jest współautorem narzędzia JRebel, służącego do szybkiego redeploy’a naszych aplikacji, bez konieczności restartowania serwera. Szkoda, że rozwiązanie jest płatne:/

Następnie wybór prezentacji był bardzo ciężki i w końcu poszedłem na Andres’a Almiray’ego z prezentacją Polyglot Programming. Prelegent porównywał jave, groovy’ego, scalę, i clojure. Mi to trochę przypominało onanizm składniowy. Może przykłady były źle dobrane do tego, aby pokazać przewagę pewnych języków nad innymi? Później autor pokazał, że można łączyć te języki ze sobą.

Na koniec poszedłem jeszcze na prezentację dra Jim’a Webber’a pt. A programmatic introduction to Neo4j. Prześmieszny koleś i na scenie robił niezłe show. Biegał, rzucał żartami i cieszył się jak publiczność atakowała go pytaniami. Co do wykładu, to najpierw ogółem opowiadał o NoSQL, że coraz więcej danych przechowujemy i że są one coraz bardziej skomplikowane. Najpierw kilka godzin modelujemy nasze dane, rozpisujemy relacje, tworzymy bazę danych, a na koniec i tak robimy denormalizację, bo nasza baza nie wyrabia. Jim podał dobre przykłady, gdzie można wykorzystać bazy grafowe. Porównał szybkość wyszukiwania naszych przyjaciół w typowym serwisie społecznościowym. Przewaga Neo4j w stosunku do relacyjnej bazy danych była tutaj miażdżąca. Jim polecał ściągnięcie tutoriala o Neo4j z github’a: https://github.com/jimwebber/neo4j-tutorial.

Dodatkowo dostęp do Neo4j z poziomu innych języków, może łatwo się odbywać przez REST’a. Jeśli chodzi o poziom rozdzielenia transakcji w Neo4j to jest to dostęp serializowany, ale na używanym podgrafie. Bardzo fajna prezentacja, szkoda, że dopiero na koniec konferencji.

Gdzieś tam w międzyczasie było jeszcze losowanie książek i innych nagród na stoiskach sponsorskich, ale na nic się nie załapałem.

Zostałem jeszcze w Krakowie na sobotę na Community Day. Tam już organizatorzy byli kompletnie wyluzowani, gdyż odbywało się to w pobliskim hotelu i było o wiele mniej uczestników (większość w piątek wieczorem pojechała do domu).

Na Community Day najpierw uczestniczyłem w Visage Android Hands-on Lab, prowadzonym przez Stephen’a Chin’a. Przedstawiał on coś co się nazywa Visage i służy do budowania GUI w JavaFX m.in. na Androida. Niby mniej tekstu i przyjemniejszy w czytaniu niż XML, ale jakoś nie do końca się przekonałem. Prezentacja była trochę niedopracowana i właściwie pomagaliśmy Stephan’owi ją usprawnić.

Autor przygotował obraz wirtualnej maszyny z kompletnym środowiskiem. Pomysł dobry, ale wykonanie trochę słabe. Początkowo dużo grzebaliśmy w podstawowym edytorze tekstu, dodając nowe funkcjonalności do naszej aplikacji. Wiązało się to ze zgadywaniem, w którym pakiecie może leżeć dana klasa. Później kopiowaliśmy pliki do świeżego projektu, modyfikowaliśmy XML’e, po to aby móc w końcu uruchomić całe cudo w NetBeans’ie (akurat był zainstalowany na wirtualnym obrazie). Ze względu na różne problemy uczestników po drodze, nie udało nam się zrealizować całości.

Po „laborce” był obiad. I tu o dziwo był obiad hotelowy, smaczny i całkiem spory wybór. Kto chciał mógł również sobie zamówić piwko.

Po obiedzie poszedłem jeszcze na prezentacje Tomasza Kaczanowskiego, pt. Who watches the watchmen? - on quality of tests. Właściwie jakieś 85% omawianych zagadnień już gdzieś wcześniej słyszałem i wiele nowego się nie nauczyłem. Mimo wszystko prezentacja była fajna z dobrym angielskim prelegenta i kameralnym gronem słuchaczy.

Tego dnia jeszcze dostałem od kolegi Krzyśka fajną nalepkę na klawiaturę, ze skrótami do IntelliJ IDEA. Podobno rozdawali to dzień wcześniej na jakimś wykładzie, ale mnie to ominęło. Jak wygląda taka klawiatura (i nalepki) można zobaczyć na blogu Hamlet’a D'Arcy.Tak samo okleję swoją klawiaturę w laptopie:) Przydało by się jeszcze coś takiego dla Eclipse’a.

Podsumowując uważam konferencję za udaną. Jedynie trochę obiad był kiepski, ale poziom prezentacji był wysoki. Wiadomo, że czasem się trafiło tak, że nie bardzo było na co iść, no ale trudno. Niemal na każdej konferencji się tak zdarza. Teraz zostaje czekać na publikacje prezentacji i nagrywanych filmów z wystąpień. Za rok trzeba się znów tam pojawić.

A już niedługo: Confitura (dawniej Javarsovia). Obecnie trwają prace na wyborem tematów, ale już wkrótce powinna ruszyć rejestracja uczestników. Już się nie mogę doczekać.

Wrażenia po konferencji GeeCON: Conference Day I

Dzięki uprzejmości mojego aktualnego pracodawcy, firmy Capgemini  mogłem wziąć udział w konferencji GeeCON. Co prawda musiałem przez część czasu stać na stanowisku sponsorskim, ale i tak sporo skorzystałem z wykładów. Zacznijmy od początku.

Do Krakowa przyjechałem razem z kolegą z pracy w środę wieczorem. Po zameldowaniu się w hotelu i chwili odpoczynku, poszliśmy zobaczyć kino, w którym miała się odbywać konferencja. Część stanowisk sponsorskich była już rozłożona, a że było już późno, postanowiliśmy się rozłożyć następnego dnia z samego rana. Pojechałem jeszcze się spotkać z ziomkiem z rodzinnego miasta i do hotelu wróciłem około północy. Poprosiłem jeszcze w hotelu o żelazko i deskę do prasowania, ale się nie doczekałem :/

W czwartek wstałem około 5.40, aby móc pójść jak najwcześniej na miejsce konferencji i rozłożyć stanowisko sponsorskie. Na miejscu byliśmy chwilę po 6 i dobrą godzinkę zajęło nam składanie całości. Później jeszcze powrót do Hotelu na śniadanko i z powrotem na konferencję.

Chwilę po 8.00 zaczęli się schodzić pierwsi uczestnicy. Dla każdego uczestnika był zestaw: duża ekologiczna torba, koszulka i kubek. Bardzo podobała mi się ulotka IntelliJ IDEA, na której były wypisane skróty klawiaturowe. Fajna pomoc na początek nauki nowego środowiska. Trzeba powiesić w widocznym miejscu i często zerkać. Ponadto był jeszcze program z opisem konferencyjnych wykładów, gazetka Open Source Journal i trochę spamu.

Z początku konferencji stałem na stoisku sponsorskim, a pierwszy wykład na który dotarłem to była prelekcja: Dra Heinz’a Kabutz’a pt. Reflection Madness. Autor jest jednym z redaktorów serwisu javaspecialists.eu. Było to szczególnie widać po formatce prezentacji i sporej liczbie odwołań do artykułów w tym serwisie. Generalnie sporo prelegentów nie trzymało sie standardowej formatki, co mi się nie podobało.

Co do samej prezentacji to było dużo o mechanizmie refleksji w Javie. Początkowe możliwości które autor pokazywał były mi znane, gdyż używałem je intensywnie w pracy magisterskiej. Późniejsze przykłady były jednak bardziej zaawansowane i dzięki temu mechanizmowi można wszystko zrobić, na co domyślnie kompilator Javy nam nie pozwala. Nie jest to mechanizm, który się wykorzystuje w codziennej pracy, ale znajomość tego się przydaje. Końcowa konkluzja jest taka, że warto stosować SecurityManager w miejscach narażonych na hakowanie naszego kodu. No i w wolnym czasie trzeba będzie przejrzeć posty publikowane na javaspecialists.eu.

Po wykładzie był obiad. Nie był on rewelacyjny: ryż z kawałkami mięsa i sos. Do tego nie było gdzie usiąść, no ale trudno. Kino nie było w całości wynajęte (jedynie 3 sale i hol), więc nawet organizacyjnie było by to trudne. Organizatorzy poszli trochę po kosztach, ale miejsce konferencji rekompensuje to niedociągnięcie. Możliwość oglądania prezentacji na ekranie kinowym, z porządnym nagłośnieniem i wygodnymi fotelami sprawia, że nawet w ostatnim rzędzie można w pełni skorzystać z konferencji.

Po obiedzie udałem się na prezentację Michaël’a Figuière’a i Cyrille’a Le Clerc’a pt. NoSQL & DataGrid from a Developer Perspective. Panowie byli przedstawicielami firmy Xebia i pochodzili z Francji. Gdybym wcześniej zwrócił na to uwagę, to bym się zastanowił, czy iść na ten wykład. Słuchanie francuskiego angielskiego nie jest łatwe, ani przyjemne. Prelegenci pokazywali dużo obrazków i wiedzy, ale bez konkretów, reklamując na końcu swoją firmę. Fajnie, że pokazali podejście do transakcji w rozwiązaniach NoSQL. Mianowicie można dodać obiektom metody typu DO i UNDO. Przykładowo jeśli mamy koszyk internetowy na sprzedawane produkty i ograniczoną ilość produktów, to jedna metoda wkłada do koszyka towar, zmniejszając liczbę dostępnych produktów w bazie danych, a druga cofa tą operację. Gdy dojdzie do realizacji zamówienia i się okaże, że któryś z produktów jest niedostępny i gdy użytkownik wycofa się z zakupów, to dla dostępnych produktów wywołujemy metodę typu UNDO. A wszystko odbywa się bez transakcji. Dodatkowo mieli fajny styl rysunków, z taką kreską, jakby malowaną grubym ołówkiem lub kredką świecową.

Podczas całej konferencji brakowało mi pani z dzwoneczkiem, informującej o rozpoczęciu wykładów. Widziałem takie rozwiązanie na którejś z poprzednich konferencji i było ono bardzo praktyczne. Brak „naganiacza / przypominacza” powodował, że się prelekcje ciągle opóźniały i przeciągały. Przerwy jednak miały sporo zapasu czasowego i pozwalały / dopuszczały takie sytuacje.

Kolejną prezentacją, którą odwiedziłem, było drugie wystąpienie dra Heinz'a Kabutz'a pt.
Productive Coder. Szkoda, że prelegent nie wyświetlał na ekranie skrótów klawiaturowych z których korzysta. Używał on środowiska IntelliJ IDEA. Co mi się spodobało, to równoczesne dodawanie kilku polom w klasie tego samego zakresu, wyświetlanie linii w IDE oddzielających kolejne metody, hotkey do przejścia w tryb pełnego okna… Musze poszukać, jakie to są skróty. Prezenter twierdził, ze powinniśmy poświęcić 10 godzin na poznawanie hotkey’ów w naszym środowisku programistycznym. Całkowicie się zgadzam. Uważam, że warto tu zastosować programowanie w parach i oglądanie screencast'ów lub pracy innych programistów.

Później Heinz pytał się publiczności o to, czy obiekt typu String jest mutable czy immutable. My programiści de facto z niego korzystamy jako immutable, ale w rzeczywiśtości jest mutable, czyli modyfikowalny. Ilustruje to poniższy kod:

String myText = "My Example String";
Set<String> mySet = new HashSet<String>();
mySet.add(myText);
System.out.println(myText);

Gdy ustawimy breakpointa na trzeciej linii to zobaczymy, że wewnętrzne pole hash w obiekcie myText ma wartość 0. Po wykonaniu 3ciej linii zmieni się ono na inną wartość. Obiekt zmienia więc swój stan. Skąd sie to bierze? Mianowicie podczas dodawania tekstu do zbioru, wywoływana jest metoda hashCode() na obiekcie myText i obliczana jest wartość hash’a. Żeby nie obliczać jej wielokrotnie, to jest ona zapamiętywana do późniejszego użycia. Jako, że obiekty typu String są używane zazwyczaj w kontekście, gdzie wartość ta nie ma znaczenia, to nie jest ona obliczana w trakcie tworzenia obiektu – wiadomo wydajność.

Doktor zachęcał również do wykorzystywania inspekcji kodu dostępnych w IntelliJ IDEA (menu Analyze -> Inspect Code...). Narzędzie potrafi między innymi wyszukać pola, które mogą mieć mniejszy zakres widoczności, pola które można zmienić na finalne, lub są niezainicjowane itd. Generalnie to potężne narzędzie do statycznej analizy kodu, które od razu potrafi wprowadzić poprawki do projektu. Szczególnie warto je wykorzystać, przy otrzymaniu odziedziczonego kodu po kimś. Dzięki niemu można znacząco pozbyć się nieużywanego kodu, który zaśmieca cały projekt.

Prelegent pokazywał jeszcze ciekawe komentarze w kodzie SDK, które nic nie wnoszą i jak się zmieniają w kolejnych wersjach SDK. Proponował on wyłączyć wszelkie automatyczne generowanie komentarzy, gdyż to nic nie daje. Nawiązała się dyskusja ze słuchaczami, czy warto stosować komentarze czy nie. Publiczność twierdziła, że należy pisać kod tak, aby był zrozumiały sam przez siebie. Heinz twierdził jednak, że kod mówi jak, a komentarz dlaczego tak a nie inaczej. Pokrywa się to z informacjami, które ostatnio przeczytałem w książce: Kod doskonały Steve’a McConnell’a. Ponadto jak nie jesteśmy w stanie napisać dobrego komentarza, to oznacza to, że sami nie wiemy jak nasz kod funkcjonuje i powinniśmy go poprawić.

Później miałem iść na prezentację Hamlet’a D'Arcy’ego  pt. New Ideas for Old Code, ale jakoś długo się zbierałem i w końcu nie doszedłem, czego później żałowałem.

Następnie chciałem iść na Aslak’ena Knutsen’a na prezentację Arquillian: Real Java enterprise testing, ale gdy się dowiedziałem, że chodzi o testowanie EJB z całym kontekstem kontenera, to sobie dałem spokój. Staram się trzymać od takich ciężkich rzeczy z daleka. Ostatecznie poszedłem więc na Nicolas’a Leroux’a, Morten’a Kjetland’a: Play! framework: a revolution in the Java world. I znów Francuzi. Co prawda jeden miał dobry angielski, ale mało mówił, gdyż stał obok, lub kodował na żywo, a drugi opowiadał, co ten pierwszy pisze. Szkoda tylko, że nie korzystał ze skrótów klawiaturowych, tylko właściwie wszystko pisał ręcznie, prawie jak w notatniku. Generalnie fajny pomysł na prezentację – jeden koduje, a drugi mówi o co chodzi.

Prelegenci to autorzy przedstawianego framework’a. Fajnie, że nie trzeba kompilować całego kodu po wprowadzeniu małej zmiany, tylko wystarczy odświeżyć stronę w przeglądarce. Ciekawe jak to we wnętrzu jest zorganizowane? I jak coś się sypnie, to bezpośrednio w przeglądarce widzimy w której linii kodu i co w niej jest! Prelegenci napisali na szybko czat przez przeglądarkę i pozwolili publiczności się połączyć i popisać. Po kilku testowych wpisach zaczęły się zgodnie z moimi przewidywaniami „ciekawsze” wpisy, typu: „Euro 2012 w Łodzi”. Na koniec ktoś jeszcze napisał Cross-site scripting i wyświetlił komunikat na ekranie, ukazując słabość framework’a. Podobno w Lift’cie jest to wbudowane we framework.

I to był ostatni wykład pierwszego dnia konferencji. Wieczorem jeszcze byłem na imprezie konferencyjnej w klubie Pauza na Florianskiej. Można było tam pogadać z innymi uczestnikami, wypić piwko i powymieniać się spostrzeżeniami. Wiadomo, że nie można było poszaleć, gdyż jeszcze czekał nas drugi dzień konferencji, o którym w kolejnym wpisie.

sobota, 7 maja 2011

Inne podejście do przechowywania danych w systemie Android, z wykorzystaniem db4o i NetBeans 6.9

W systemie Android domyślnie mamy dostęp do relacyjnej bazy danych SQLite w której możemy zapisywać informacje z naszej aplikacji. Jest to typowy sposób dostępu do danych w tym systemie. Nie jest dziwne, że do tego systemu została wybrana ta baza. Nie posiada ona wielu magicznych dodatków (jak obecnie popularne kombajny) i założenia jest „Lite” (przynajmniej z nazwy). Z innej strony jest to baza o ciekawym stosunku kodu źródłowego do testów. Odsyłam do artykułu: Extremalne testowanie w SQLite Pawła Lipińskiego. Jak skorzystać z tej bazy jest już opisane na blogu Mirosława Stanka (część 1, część 2, część 3) jak i na helloandroid.  Ja nie będę po raz kolejny opisywał tego rozwiązania, ale postaram się poniżej pokazać inne (ciekawsze?) podejście do tematu, z wykorzystaniem obiektowej bazy danych.

DataBase For Objects, zwana powszechnie db4o, to interesująca alternatywa dla SQLite w systemie Android, jeśli chodzi o składowanie danych. Od wersji 7.5 biblioteka daje wsparcie dla tej platformy. Poniżej przedstawię jak zbudować projekt w NetBeans’ie 6.9 z wykorzystaniem tej biblioteki.

Tworzymy w NetBeans’ie nowy projekt typu AndroidApplication. Następnie do bibliotek dodajemy JAR’a zawierającego db4o.


Następnie warto skorzystać z klasy Db4oHelper przedstawionej przez Damasia Maneiro (niestety nie mam pojęcia jak to po polsku odmienić) w artykule na dzone.com: Using db4o in an Android application. Jest tam sporo kodu odwołującego się do klas z tamtejszego projektu, więc pozwoliłem sobie trochę ten kod zmienić do naszych potrzeb. Listing poniżej.

public class Db4oHelper {

    private static ObjectContainer oc = null;
    private Context context;

    public Db4oHelper(Context ctx) {
        context = ctx;
    }

    public ObjectContainer db() {
        try {
            if (oc == null || oc.ext().isClosed()) {
                oc = Db4oEmbedded.openFile(dbConfig(), 
                        db4oDBFullPath(context));
            }
            return oc;
        } catch (Exception ie) {
            Log.e(Db4oHelper.class.getName(), ie.toString());
            return null;
        }
    }

    private EmbeddedConfiguration dbConfig() throws IOException {
        EmbeddedConfiguration configuration = 
                Db4oEmbedded.newConfiguration();
        return configuration;
    }

    private String db4oDBFullPath(Context ctx) {
        return ctx.getDir("data", 0) + "/" + "database.db4o";
    }

    public void close() {
        if (oc != null) {
            oc.close();
        }
    }
}

Mamy do dyspozycji publiczny konstruktor, który jako argument przyjmuje Context – podobnie jak w SQLite. Potrzebne nam to będzie do umieszczenia pliku z bazą danych w miejscu, gdzie znajdują się dane aplikacji. Następnie mamy metodę db(), która zwraca nam instancję klasy odpowiedzialnej za połączenie z bazą. Mamy jeszcze metodę zwracającą nam konfigurację bazy (domyślna nam początkowo wystarczy) i ścieżkę do pliku z bazą. Na koniec metoda do zamknięcia połączenia z bazą.

Teraz można już napisać klasy, które chcemy składować w bazie danych. Mamy kilka możliwości jak to zrobić. Ja poniżej przedstawię prosty obiekt POJO i odpowiadającą mu klasę DAO. Można oczywiście to wszystko w jedną klasę wrzucić, ale tak będzie ładniej i poprawniej. Poniżej przykładowy kod klasy User.

public class User {

    private String login;
    private String password;

    public User(String login, String password) {
        this.login = login;
        this.password = password;
    }

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

W klasie są definiowane 2 pola typu String o nazwach login i password oraz odpowiadające im gettery i settery. No i jeszcze konstruktor przyjmujący te parametry. Jeśli ktoś woli programować w stylu funkcyjnym, to można zrobić pola final i wyrzucić settery. Db4o i tak zadziała, gdyż do ustawiania wartości wykorzystuje refleksje do pól składowych, a nie do setterów.

Proszę zwrócić uwagę, że klasa nie posiada żadnego pola w stylu ID. Dodawanie do klas persystentnych identyfikatorów, to niemalże konieczność w świecie relacyjnym, gdyż dzięki identyfikatorom tworzy się relacje i złączenia przy zapytaniach. W bazach obiektowych tego nie potrzebujemy! Mamy przecież referencje i kolekcje.

Poniżej kod klasy DAO dla klasy User:

public class UserDao {

    private ObjectContainer db;

    public UserDao(Context context) {
        Db4oHelper db4oHelper = new Db4oHelper(context);
        this.db = db4oHelper.db();
    }

    public void saveOrUpdate(User user) {
        db.store(user);
    }

    public void delete(User user) {
        db.delete(user);
    }

    public List<User> getAll() {
        return db.query(User.class);
    }
    
    public List<User> getByLogin(String login) {
        User example = new User(login, null);
        return db.queryByExample(example);
    }

    public List<User> getByLoginAndPassword(
                 String login, String password) {
        User example = new User(login, password);
        return db.queryByExample(example);
    }
}


Klasa posiada konstruktor, za pomocą którego do klasy przekazujemy obiekt typu Context. Jest to klasa android’owa, za pomocą której Db4oHelper może się dostać do odpowiedniego miejsca na zapisanie pliku z bazą. Następnie pobieramy i zapamiętujemy obiekt typu ObjectContainer pochodzący z biblioteki db4o i za jego pomocą odbywa się dostęp do danych. Dalej mamy operacje tworzenia, modyfikacji, usuwania i pobierania wszystkich obiektów - nic specjalnego, ot proste wywołanie pojedynczych metod.

Trochę (ale tylko troszkę) ciekawsza jest metoda getByLogin(), która korzysta z query by example. W skrócie, ta metoda wykonywania zapytań, polega na utworzeniu najpierw obiektu, który będzie przykładem, a następnie wywołaniu odpowiedniej metody zwracającej wszystko, co do danego wzrorca pasuje. Domyślne wartości pól klasy są dopasowywane dowolnie, a te zmodyfikowane dokładnie. W tym przypadku zostaną zwrócone obiekty posiadające ustawione pole login na takie samo jak przekazane w argumencie metody. No prościej się chyba nie da. Istnieją w db4o jeszcze inne bardziej wyrafinowane metody zapytań, ale to nie temat na ten wpis.

Ludzie doświadczeniem z dużymi systemami i relacyjnymi bazami danych, widząc powyższy kod, zaraz zaczną krzyczeć: „a co z dostępem równoległym?”, „a gdzie początek i koniec transakcji?”, itd. Otóż w ogólności db4o wspiera ACID, a poziom izolacji transakcji ma ustawiony na Read Committed. Pytanie z mojej strony: czy rzeczywiście wszędzie tego potrzebujemy? Z tego, co mi wiadomo, to zdarzenia z aktywności w Androidzie są obsługiwane synchronicznie, tzn. w tym samym wątku co GUI. Jeśli nie tworzymy dodatkowych wątków do obsługi zdarzeń (ze względu na ich banalność i szybkość), to nie potrzebujemy transakcji.

Dobra, to teraz by się przydało jakieś GUI dorobić, aby można było zobaczyć jakiekolwiek efekty działania. Po uruchomieniu aplikacji będą się pojawiać dwa przyciski: Create New User i Login. Te będą kierować już do następnych ekranów. Tam będzie można utworzyć nowego użytkownika (i oczywiście go zapisać w bazie), albo się zalogować do aplikacji (na podstawie loginu i hasła zapisanego w bazie). Nie pokazuję tutaj jak utworzyć GUI, gdyż nie jest to tematem tego artykułu. Całkowity kod zamieszczam na końcu wpisu.

Przy pierwszej próbie uruchomienia tak skonstruowanej aplikacji dostaniemy błąd. Jeżeli nie zepsuliśmy niczego po drodze to problem jest jasny. Samo dołączenie biblioteki db4o do projektu nie spowoduje jej dołączenia w trakcie budowy projektu. Należy jeszcze dodać do build.xml następujący target (lub podobny):


    
        
    


Uważam, że środowisko programistyczne powinno być na tyle inteligentne, aby się troszczyło za nas takimi detalami. No ale cóż, nie można mieć wszystkiego. Teraz już powinno pójść gładko i jeśli nic nie popsuliśmy w XML’ach to powinniśmy zobaczyć naszą aplikację. Przykładowe screeny poniżej:



Pod koniec chcę zaznaczyć, ze NetBeans 6.9 nie jest idealnym środowiskiem do pisania aplikacji androidowych (może trzeba jeszcze poczekać?). W trakcie pracy nad projektem natrafiłem na sporo utrudnień. Przykładowo, podczas refaktoringu, po przeniesieniu klasy aktywności, aplikacja przestawała działać. Trzeba było wówczas w AndroidManifest.xml trochę pogrzebać i poprawić nazwy klas. Również zmiana nazwy pakietu wymuszała dodatkowe grzebanie w project.properties.

Z ciekawości sprawdziłem jeszcze jak sobie ze wsparciem Androida radzi IntelliJ IDEA (tak w końcu ją zainstalowałem :) ). Tutaj przeniesienie klasy do innego pakietu nie stanowi problemu. Podobnie z dodaniem biblioteki db4o do projektu. Co do zmiany nazwy pakietu to napiszę o tym w następnym poście (aby wszystko na raz nie było w jednym). Dodatkowo Idea od razu pokazuje Log konsolę z Androida. Chcą ją aktywować w NetBeans'ie trzeba kliknąć: Window -> Output -> ADB Log.

Jeszcze w między czasie tworzenia tego wpisu (nie powstał on w jeden dzień) pojawił się NetBeans 7.0. Tam jednak nawet nie mogłem dodać żadnej zewnętrznej biblioteki do projektu android'owego, więc ewentualna migracja do nowego środowiska musi poczekać.

Link do kodu:

db4oOnAndroid.zip

git://github.com/mstachniuk/db4oOnAndroid.git

//Update (25.09.2011)
Jak słusznie zauważył mój przyjaciel Michał, skoro otwieramy połączenie do bazy danych, to musimy je również zamknąć. Można to zrobić w MainActivity.java w przeciążając metodę onDestroy():

@Override
protected void onDestroy() {
    Db4oHelper db4oHelper = new Db4oHelper(this);
    db4oHelper.close();
    super.onDestroy();
}