Stronnice Chlebika – Newbie Java Blog

marzec 3, 2009

Grailsujemy z bazą, czyli tworzymy linki cz.1

Zaszufladkowany do: Grails, Hibernate, HowToJava, Java, NetBeans — chlebik @ 12:04 am

Grails implementuje wzorzec MVC, choć do tej pory o owym ‘modelu’ to niewiele napisałem. Pora to zmienić, tym bardziej, że bez modelu to nasza aplikacja nie różni się zbytnio od stronki opartej na tabelkach tak mniej więcej sprzed 10 lat.

W poprzednim wpisie wspomniałem, że tworzenie aplikacji w Grails jest oparte na mechanizmie ’scaffoldingu’. Kolejne kroki polegają na:
- zbudowaniu klasy domenowej (domain class, tłumaczenie moje)
- napisanie do niej testów
- wygenerowanie dla tejże klasy kontrolera

Każdy obeznany ze wzorcem MVC w tym momencie zda sobie sprawę, iż nie jest to byle co. Często samo utworzenie modelu jest żmudną robotą, a do tego jeszcze testy i kontroler – wpis będzie długi z całą pewnością (dla niezorientowanych: piszę kolejne posty jednocześnie czytając i kodując zatem nie wiem co ostatecznie wyniknie na samym końcu :). Na pierwsze zapoznanie się z całym procesem wybrałem implementację strony z linkami. Nie jest ona specjalnie wymagająca ze strony widoku, kontroler też nie za bardzo, zaś model powinien okazać się dość prosty – w końcu cóż skomplikowanego może być w tabelce z linkami?

Wpierw należy stworzyć domain class, co da się łatwo osiągnąć klikając prawym przyciskiem na projekcie i wybierając New->Grails Domain Class. Nadajemy plikowi nazwę Linki i po chwili możemy cieszyć się nową klasą, a także stworzonym automatycznie plikiem do testów integracyjnych (integration tests). O samych testach napiszę w kolejnych wpisach (choć w myśl idei Grails wpierw powinniśmy napisać testy, a potem dopiero logikę), teraz przyjrzyjmy się naszemu modelowi.

class Linki {
String adress;
String description;
Date addDate;
Integer category_id;

static constraints = {
adress(blank:false, maxSize: 256, nullable: false)
addDate()
description(blank:false, maxSize: 1024, nullable:false)
category_id(blank:false, nullable:false)
}

}

Zasadniczo nie wiem czy jest sens cokolwiek wyjaśniać. Nasz model to po prostu reprezentacja konkretnych rekordów w tabeli bazy danych. Tabela ta dopiero powstanie, ale już właśnie na etapie budowy (jak i pisania testów), można przemyśleć strukturę tejże tabeli i opisać ją poprzez konkretne zapisy w klasie modelu. Jak widać na powyższym przykładzie nasz pojedynczy rekord będzie miał na pewno adres (o pewnej maksymalnej długości), opis (też maksymalna długość), datę dodania oraz ID kategorii linków, który to będzie kluczem obcym wskazującym na pojedynczą kategorię, do której link jest przypisany (musi być przypisany, stąd ograniczenie category_id do wartości różnych niż NULL i pustych). Grails (lub też sam ORM – również Hibernate) doda do tego rekordu w sposób automatyczny własność ID, a także wersję – więcej o tym w kolejnych wpisach.

To tyle. Naprawdę. To już koniec, pomijając testy, mamy działający model. Teraz zatem wypadałoby stworzyć kontroler, który ogarnie ten temat. Prawy klik na katalogu z kontrolerami, New->Grails Controller, wpisujemy nazwę Linki i po chwili magii Netbeans mamy klasę kontrolera, kolejny test integracyjny i folder na widoki powiązane z nowym kontrolerem. Oto nasza klasa:

class LinkiController {
def index = { }
}

Nasze zadanie jest proste – trzeba istniejący kod zamienić na taki:

def scaffold = Linki

Uruchamiamy projekt, przechodzimy pod adres http://127.0.0.1/Howtojava/linki/list i co? Taaak, wiem, że widok budujący. Oto Grailsy automatycznie wygenerowały stronkę z pełną funkcjonalnością CRUD. Oczywiście wygląda to… nie wygląda, zwykłe tekstowe linki z parametrami przekazywanymi przez GET, no ale miło zobaczyć coś powstałe z niczego.

linczek

Mamy najzwyklejszą listę – kwestia tylko w tym, iż nie mamy za bardzo czego na niej wylistować. Zawsze jednakże możemy kliknąć New Linki i oto co ukaże się naszym oczom:

createlinki

Formularz wymaga dopracowania – nazwy pól powinny być po polsku, komunikaty o błędzie też (spróbujcie utworzyć nowy link nie wpisując np. liczby całkowitej w polu categoryid). Pojawi się komunikat po wysłaniu formularza. Do tego wybór kategorii powinien być rozwijaną listą, a nie wpisywaniem liczby całkowitej. No ale to temat na najbliższe wpisy. Wpiszmy testowe dane i utwórzmy nowy link. Oto efekt po wysłaniu formularza:

newlink

Pokazał nam się dodany właśnie wpis – możemy go edytować, albo też usunąć. Żyć nie umierać. Wróćmy do listy wszystkich linków – http://localhost:8080/Howtojava/linki/list – jak widać mamy dodany właśnie link pięknie pokazany na pozycji pierwszej. Jedyny minus to to, że po zakończeniu działania aplikacji dane te zostaną utracone. Zajmę się tym w następnym wpisie.

marzec 1, 2009

Konfiguracja Grails

Zaszufladkowany do: Grails, HowToJava, Java, NetBeans — Tagi:, , — chlebik @ 9:10 pm

Zgodnie z obietnicą z poprzedniego wpisu postanowiłem zawrzeć bliższą znajomość z plikami konfiguracyjnymi Grails. Zdziwiłem się trochę…

Ja rozumiem, że ‘konwencja ponad konfiguracją’, ale zasadniczo okazało się, że we frameworku nie za bardzo jest co konfigurować. Dokumentacja Grails nie jest zbyt rozbudowana w tej dziedzinie, ale mimo to daje się znaleźć w niej kilka ciekawych rzeczy.

Wpierw należy zaznaczyć, że podstawowym plikiem konfiguracyjnym jest Config.groovy, który radośnie czeka na edycję w katalogu conf. Dość istotne jest to, że możemy go swobodnie wyedytować, aby zapisać w nim dane (konkretnie zmienne), które chcielibyśmy uznać za część konfiguracji. Wystarczy zatem do pliku konfiguracyjnego dodać taką oto linijkę:

moj.email = "moj@adres.email.pl"

By następnie w kodzie aplikacji wyciągnąć te dane w równie łatwy sposób:

println(grailsApplication.config.moj.email)

Powyższa metoda jest dostępna tylko w kontrolerach i plikach znaczników. Zaś bardziej uniwersalną metodą jest odwołanie się do ConfigurationHandlera

import org.codehaus.groovy.grails.commons.*
def config = ConfigurationHolder.config
assert "world" == config.moj.email

Jak widać rzecz jest prosta jak konstrukcja gwoździa. Idąc dalej – plik konfiguracyjny zawiera kilka ciekawych ustawień, ale nie ma ich znowu tak wiele. Po szczegóły odsyłam zainteresowanych do dokumentacji – jej przepisywanie mija się z celem. Poniżej subiektywna lista elementów, które lepiej poznać od razu, gdyż od razu mogą się przydać:

  • grails.views.gsp.encoding – raczej zrozumiałe, a jakże przydatne. Domyślną wartością jest oczywiście UTF-8.
  • grails.serverURL – zawiera podstawowy adres serwera naszej aplikacji. Jest domyślnie używany jako podstawa do tworzenia linków poprzez wywoływanie metody createLink i podobnych.
  • środowiska wykonawcze – podobnie jak w Ruby on Rails aplikacja może być konfigurowana i uruchamiana w 3 różnych domyślnych środowiskach. Developerskim, testowym i produkcyjnym. Dla każdego z nich możemy zafundować sobie oddzielną konfigurację. Jest to możliwe w podstawowym pliku konfiguracyjnym (przypominam config.groovy), a także w konfiguracji dostępu do źródeł (głupie tłumaczenie, chodzi oczywiście o DataSource.groovy). Konkretnie konfigurowaniem połączenia z bazą danych zajmę się już niedługo (wraz z pierwszym jej użyciem), ale oto szybki przykład jak wygląda podział na środowiska w konfiguracji (przykład z dokumentacji):

    dataSource {
    // common settings here
    }
    environments {
    production {
    dataSource {
    url = "jdbc:mysql://liveip.com/liveDb"
    }
    }
    }

    Kolejne środowiska (test i development) konfigurujemy podobnie. Dla ciekawych – Netbeans pozwala na zmianę środowiska uruchomieniowego poprzez prawy przycisk myszy na nazwie projektu->Properties->Active Grails Environment. Dzięki temu można bezboleśnie przenosić się między środowiskami co ułatwia pracę.

To tyle na szybko i zasadniczo dość wyczerpująco. Jak już wspomniałem ciekawych odsyłam do instrukcji, gdzie można poczytać o logowaniu, wersjonowaniu, czy eksternalizacji konfiguracji.

luty 28, 2009

Grailsów część trzecia – statyczna zawartość i mapowanie adresów

Zaszufladkowany do: Grails, HowToJava, Java, NetBeans — Tagi:, , , , — chlebik @ 9:06 pm

Grails w znaczącej mierze opierają się na zasadzie ‘konwencja ponad konfigurację’. Dlatego też tworzenie aplikacji działa w oparciu o tzw. scaffolding, co można przetłumaczyć jako ‘rusztowanie’. Nie byłbym rzecz jasna sobą, gdybym nie próbował tego tematu obejść :)

Choć to obejście przyszło mi dość łatwo. Otóż w myśl mądrych myśli autorów frameworka wpierw powinniśmy utworzyć klasę modelu (domain class), potem napisać do niej testy jednostkowe, uruchamiać je i zmieniać klasę, aż przejdzie ona wszystkie testy z powodzeniem i dopiero po tym napisać kontroler. Ciekawe podejście – z pewnością użytkownicy RoRa znają je o wiele lepiej niż prosty koder PHP. Domyślnie bowiem używając w pracy Zend Frameworka, wpierw tworzę sobie choćby namiastkę kontrolera, gdyż gdzieś trzeba uruchomić pisane klasy modelu. Jak widać w Grails temat został trochę przestawiony, ale co z tego wynika napiszę pewnie w kolejnych wpisach.

Teraz zaś postanowiłem rozejrzeć się trochę po projekcie pozostając wciąż blisko widoku, bez zagłębiania się specjalnie w szczegóły modelu. Poprawiłem trochę CSS (wygląda dobrze nawet pod Internet Explorerem), a także zreorganizowałem menu. Okazało się, że w serwisie będzie kilka miejsc, które będą miały charakter wybitnie statyczny, to znaczy, będzie to wyświetlenie 1 widoku, który to jednakże mógłby mieć swój unikalny adres, ale z drugiej strony, nie ma sensu wrzucać luźnych plików do głównego katalogu /web-app. Przykładem takich stron są choćby odnośniki ‘O serwisie’ czy ‘Linki’. Oczywiście w przypadku tej aplikacji problem jest trochę wydumany, ale w rzeczywistych aplikacjach ilość takich stron może już trochę wzrosnąć i tym samym dobrze byłoby od samego początku mieć dla nich oddzielne miejsce.

Oto jak wygląda obecnie główna strona serwisu:

stronaobecnie

Dobrze byłoby, aby pod linkami na górze kryły się ładne adresy w postaci /strona czy /linki. Jednakże tworzenie dla pojedynczych akcji oddzielnych kontrolerów mija się z celem. Wydumałem sobie zatem, że utworzę jeden kontroler, zaś poszczególne akcje będą odpowiadały za renderowanie tych stron. Konkretne pliki widoku (*.gsp) również znajdą się w jednym miejscu (katalogu).

Wpierw należy utworzyć kontroler, który zbierze to wszystko do kupy. Klikamy zatem prawym przyciskiem na folderze ‘Controlers’ i wybieramy New->Grails Controller. W okienku wpisujemy jego nazwę (u mnie będzie to static) i klikamy Finish. Netbeans przemieli magię frameworka i utworzy nie tylko kontroler, ale też odpowiedni katalog dla widoków w folderze Views and layouts wraz z testem integracji (katalog Integration Tests). Na razie jednakże zajrzyjmy do pliku StaticController.

class StaticController {
def index = { }
}

Rozbudowane, trzeba przyznać :) Kontrukcja którą widać jest tzw. domknięciem. Jest to obiekt Javy, który jednakże wygląda i zachowuje się jak metoda. Jest to o tyle ciekawy element języka Groovy, iż nie potrzeba deklaracji zwracanego typu, a także jawnej specyfikacji parametrów. W przypadku Grailsów tak stworzone domknięcie odpowiada za to, co zostanie przetworzone podczas odwołania się do adresu w postaci /kontroler/akcja. By zaś nie pozostać gołosłownym wystarczy wpisać w adresie przeglądarki odpowiedni adres – http://127.0.0.1:8080/Howtojava/static/index – i co otrzymaliśmy?

Error 500: ServletContext must not be null

Śliczny komunikat o błędzie. Hmmmm, cóż to mogłem przegapić. ServletContext to pojęcie, które znam z JSP. Konkretnie jest to obiekt, który odpowiada za konfigurację całej aplikacji (można tam choćby umieścić dane dotyczące połączenia z bazą danych). Plikiem konfiguracyjnym aplikacji jeszcze się nie bawiłem, zatem może sprawdźmy jeszcze czy to może dlatego, że nie mamy pliku widoku. O dziwo po skopiowaniu pliku index.gsp do katalogu Views and layouts (podkatalog static) i ponownym uruchomieniu aplikacji – viola! Działa. Ciekawe… Zadanie na następny wpis – zapoznać się z konfigiem aplikacji. (PS. Okazało się, że to bug występujący w pewnych okolicznościach związany z pewnym kształtem UrlMappings.groovy. Zasadniczo nie przeszkadza i nie pojawił się więcej).

Plik kontrolera po małych zmianach wyglądał tak:

class StaticController {

def index = { }

def linki = {}

def strona = { }

}

Utworzyłem także 2 widoki – jeden to ‘linki.gsp’, a drugi to oczywiście ’strona.gsp’. Oto jak wyglądają (zmienia się tylko napis na środku):

Informacje o stronie

Wpisuję adres http://127.0.0.1:8080/Howtojava/static/strona no i proszę. Jak ślicznie to wygląda:

linki

Wygląda całkiem ładnie, problem tylko z adresem, jemu trochę do ładnego wyglądu jeszcze brakuje. Należy zatem odwiedzić katalog Configuration i tam znaleźć plik UrlMappings.groovy. Świetny tutorial dotyczący mapowania adresów można znaleźć na stronie projektu Grails i tam odsyłam zainteresowanych tematem. Natomiast u mnie plik po edycji wygląda następująco:

class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}

"/strona" (controller: "static", action: "strona")
"/linki" (controller: "static", action: "linki")

"500"(view:'/error')
}
}

Zostawiłem domyślną ścieżkę, co mi tam :) Ponownie odwiedzamy przeglądarkę, tym razem jednak wpisując adres http://127.0.0.1:8080/Howtojava/strona i… error 404. No i tu leży pies pogrzebany – należy zastopować serwer i uruchomić go ponownie, aby zmiany w kodzie aplikacji zostały wdrożone. Cóż, taka cena, którą póki co trzeba zapłacić (trzeba będzie poszukać na ten temat informacji). Po restarcie pod powyższym adresem ukaże się naszym oczom dokładnie taki sam widok jak na obrazku powyżej. Znowu sukces :)

Na koniec pomyślałem, że byłoby dobrze od razu zająć się stronami błędów. W pliku UrlMappings.groovy jak widać mamy regułę routingu dla kodu “500″. Przydałoby się jeszcze dla odróżnienia zdefiniować inny widok dla kodu “404″ no i najlepiej stworzyć dla nich wspólny kontroler. Jeszcze nie wiem jak to wygląda w Grails, ale w takim kontrolerze możnaby dla przykładu podpiąć logowanie błędów, wyświetalnie wyrzuconych wyjątków, itp. Trzeba jednakże przyznać, iż renderowanie całości dotychczasowego layoutu na stronie o błędach mija się z celem. Dlatego też postanowiłem stworzyć odchudzoną wersję layoutu dla renderowania tylko dla komunikatów o błędach (choć może i przyda się później).

Chwilka pracy (myślę, że nie muszę wklejać listingów, wszystko odbywa się tak samo jak w tym i poprzednim wpisie) i powstał nowy lekki layout, a także stosowny kontroler Errors i widoki do niego. Domyślnie Grails tworzy widok, który jest odpowiedzialny za renderowanie błędów (error.gsp). Zostawiłem go, tylko zmieniłem nazwę na servererror, aby wyrzucał wyjątki w sposób ‘widoczny’ dla mnie (na serwerze produkcyjnym oczywiście takie coś należy wyłączyć). Dodałem też ładny widok dla kodu błędu 404. Restart, uruchom i znowu problem. Okazuje się, że przy błędzie 404 – Grails w dziwny sposób nie potrafi odwołać się do zewnętrznego pliku layoutu! Czyli mój piękny odchudzony plik z layoutem na niewiele mi się zda. Po prostu renderowany jest zwykły widok (nopageerror.gsp), ale tylko tyle! Nie jest w ogóle startowany plik layoutu. Grrr, posiedziałem nad tym, poklęłem no i nic – musiałem wrzucić zmiksowany kod layoutu i samej strony do jednego pliku. Pewnikiem gdzieś jest jakaś zagowzdka z obiektem renderującycm widok, no ale na razie nie za bardzo mam czas się w ten problem zagłębiać. Najważniejsze, że mam piękną stronę dla błędu 404.

stronabledu

Grailsujemy dalej, czyli początki aplikacji w Grails

Zaszufladkowany do: Grails, HowToJava, Java, NetBeans — Tagi:, , , — chlebik @ 1:07 am

W poprzednim wpisie powiadomiłem wszem i wobec o nowym projekcie na blogu. Przyszedł zatem czas na konkrety – oto początki tworzenia aplikacji internetowej w Grails.

Wbrew wcześniejszym zapewnieniom użyte IDE to ponownie Netbeans, tyle tylko, że w wersji 6.5, która posiada wsparcie dla projektów pisanych w Groovym i Grailsach. Należy zatem zaopatrzyć się w wersję 6.5 Netbeans’a i z menu wybrać File->New Project->Groovy->Grails Project (oczywiście wypadałoby mieć w tym czasie również zainstalowane Grails i Groovy, ale jak tego dokonać napsiałem w poprzednim wpisie. IDE pobuduje nam projekt i oto co powinno pokazać się naszym oczom:

Projekt Grails

Projekt Grails

Jak na rasowy framework przystało, Grails odwalił kupę dobrej roboty, aby tworzenie projektu odbyło się łatwiej i przystępniej. Mamy zatem na razie puste katalogi z kontrolerami, modelami (domenami), usługami sieciowymi, a także kilka ciekawych rzeczy. Standardowo framework ten jest dostarczany z szeregiem bibliotek JavaScriptu, które mają w zamyśle wspomagać pracę z AJAXem. Widać tam i Prototype, a także opartą na nim bibliotekę Scriptaculous, z którymi miałem okazję pracować, ale jednak obecnie korzystam z JQuery i za nic nie chcę widzieć alternatyw :) Zmianą używanych bibliotek zajmę się później.

Mamy też katalog ‘Views and layouts’, którego przeznaczenie jest raczej oczywiste. Widoki w Grails są tworzone z użyciem Grails Server Pages (swoistej odmiany JSP). Do tematu jednakoż jeszcze za chwilkę powrócę. Warto rozejrzeć się trochę po projekcie w jego początkowej fazie. Daje to pojęcie od czego zaczynamy na samym początku pracę i da obraz zmian i ogromu pracy jaką wykona za nas Grails.

Teraz może kilka słów o projekcie, który zamierzam zrealizować. Nie raz dało się słyszeć głosy (na różnych forach), iż społeczność javovców w polskim internecie (podkreślam INTERNECIE), nie ma tak mocnego ośrodka jak choćby forum php.pl, na którym zawsze można znaleźć odpowiedzi na masę pytań i nie tylko (HydePark rządzi). Pomijając kwestie natury społecznościowej, to dobrze byłoby mieć jedno miejsce, gdzie na 99% znajdzie się odpowiedź na większość swoich wątpliwości. I tak kiedy jechałem do pracy przyszedł mi do głowy ciekawy pomysł. Może należałoby stworzyć prosty serwis (prosty, bo też tworzony w ramach nauki), w którym możnaby zamieścić pytanie z prośbą o poradę, a użytkownicy portalu mogliby na nie odpowiadać. Czyli takie forum, ale nastawione tylko i wyłącznie na porady dotyczące języka programowania, a także pokrewnych technologii. Podobne portale istnieją w odniesieniu do wielu dziedzin życia, ale moje ambicje nie sięgają tak daleko. Rozwiązań tego typu w polskim internecie przeznaczonych TYLKO DLA JAVY, jakoś nie mogłem się doszukać, zatem i ciekawy pomysł, a i może przyda się komuś :) Jakby jeszcze ktoś chciał wesprzeć tanim hostingiem to w ogóle byłoby miodzio.

W tym wpisie opiszę tylko dwa kroki – ‘oprawienie’ aplikacji w inny niż standardowy wygląd, a także dodanie biblioteki JQuery i usunięcie istniejących. To tyle na rozruch, poważniejszymi zadaniami zajmę się niedługo. Wpierw zatem wygląd. Przejrzałem szereg ciekawych propozycji i z pomocą żony wybrałem taki, który najlepiej moim zdaniem nadaje się do moich celów. Pobrana paczka składa się z obrazków, kodu CSS oraz przykładowej strony HTMLa. No i teraz po kolei.

Kod CSS wrzucamy do katalogu /css. Konkretnie znajduje się on KATALOG_APLIKACJI/web-app/css. Domyślnie tworzony jest w nim plik main.css, ale nie przejmumy się tym – zapisałem CSS dla całego layoutu pod nazwą layout.css. W tym samym katalogu (KATALOG_APLIKACJI/web-app) mamy także katalog /images. Tam zgodnie z nazwą wrzucamy pliki graficzne dla ściągniętego layoutu.

Grailsy ucieleśniają dość standardowy mechanizm – mamy zarówno layout, jak i konkretne szablony dla obecnie wyświetlanej akcji. Domyślnie (zaraz po stworzeniu projektu) posiadamy dwa pliki. Jeden to plik layoutu w katalogu Views and layouts/layouts/main.gsp, a także pierwszy plik szablonu w katalogu Web Application/index.gsp. Dla celów instruktażowych należy stworzyć kopię pliku index.gsp w tym samym katalogu – wypada tylko zmienić jego nazwę, na np. example.gsp. Na nim będziemy eksperymentować. Na razie jednakże zajmijmy się plikiem layoutu. Jego zawartość powinna wyglądać mniej więcej tak:

kodlayout1

Wygląda to na standardowy kod HTMLa ze specjalnymi tagami GSP. I właśnie te tagi są dla nas najważniejsze. Należy uruchomić naszą stronkę (prawy przycisk na projekcie->run). Netbeans puści w ruch całą maszynerię wdrożenia aplikacji i na końcu zastartuje serwer i odpali przeglądarkę (przynajmniej u mnie tak to działa :). Naszym oczom powinna ukazać się strona powitalna Grails. Zachęcam do spojrzenia w kod źródłowy strony (w przeglądarce), a następnie zapozanie się z treścią pliku index.gsp w katalogu /web-app. Ciekawe prawda? Nie jest potrzebna większa znajomość frameworka, aby zobaczyć, iż w miejsce znaczników i zostały ‘wstrzyknięte’ kawałki kodu z wyświetlanego obecnie widoku.

Zatem uzbrojeni w tę wiedzę należy teraz poinformować aplikację, aby wczytywała również kod CSS z pliku layout.css. W tym celu do pliku main.gsp należy dopisać tę linijkę:

	<link rel="stylesheet" href="${createLinkTo(dir:'css',file:'layout.css')}" />

Edycja: Dzięki mejlowi od Mariusza Pieniążka zdałem sobie sprawę, że poniższy fragment jest totalnie nielogiczny i zagmatwany. Stąd nowa wersja.

Należałoby też wyczyścić zawartość znacznika w naszym pliku layoutu (main.gsp) – zostawiamy tylko znacznik GSP . Z kolei w naszym pliku (dla przypomnienia: example.gsp) należałoby wkleić zawartość widoku ściągniętego ze strony z templejtami (link podałem gdzieś wcześniej). Jedyną rzeczą do dopisania w samym widoku jest linijka:

To co ostatecznie musimy osiągnąć to plik layoutu (main.gsp), w którym znajdują się maksymalnie rozbudowane sekcje HEAD (wszystkie znaczniki META oraz importy plików, np. CSSów czy JSa), a także dość krótka i nienarzucająca się sekcja BODY. Oczywiście w ostatecznym wyglądzie HowToJava plik layoutu trochę rozbudowałem (głównie dla obsługi sidebara), jednakże zasada jest ta sama.
Zaś plik widoku (aktualnie renderowanego) powinien zawierać w sekcji HEAD taki oto znacznik:

<meta name="layout" content="main" />

Dzięki temu layout z main.gsp zintegruje się z naszym widokiem. Do pełni szczęścia okazało się, że trzeba wyedytować plik layout.css – przy odnośnikach do plików graficznych trzeba dopisać “../”, aby Grails zobaczył obrazki. Póki co dziwne (nie wiem pod kątem czego odbywa się przeszukiwanie katalogów, no ale rozwiązanie to na razie działa). Z pewnością dowiem się już niedługo więcej na temat routingu w tym frameworku. Oto co uzyskałem po małych przeróbkach ze swojej strony (adres pod którym uruchamiam aplikację to: http://localhost:8080/Howtojava/example.gsp):

howtojava

Wygląda to już dość przyzwoicie, teraz przyszedł czas na JQuery. Ja po prostu usunąłem katalog Prototype z folderu /web-app/js i wgrałem tam ‘czystą’ bibliotekę JQuery. W pliku main.gsp dodałem tylko tę linijkę ( w sekcji <head>):

<g:javascript library="jquery-1.3.2.min" />

Przetestowanie czy JQuery jest banalnie proste. Króciutki kod wklejony bezpośrednio do pliku example.gsp powiedział prawdę:

jQuery().ready(function(){$('#logo').fadeOut();});

I po przeładowaniu strony napis ‘HowToJava.pl’ powinien powoli sobie zniknąć. Krótko mówiąc – podpięliśmy inną bibliotekę JavaSCriptu niż dostarczane standardowo. To tyle na dziś. W następnej części przedstawię technologię rusztowania (ang. scaffolding), która zgodnie z nazwą umożliwia stworzenie znacznej części aplikacji automatycznie. Na pewno będzie ciekawie.

luty 25, 2009

Grailsujemy

Zaszufladkowany do: Grails, Java, NetBeans — Tagi:, — chlebik @ 12:12 am

Dziś będzie szybko – za radą Jacka Laskowskiego postanowiłem zabrać się za Grailsy. Po przejrzeniu kilku stron w necie wiem już jedno – tak, to jest konkretne narzędzie. Jeszcze bardziej podoba mi się motto ze strony głównej projektu – Grails – the search is over.

Znikam zatem na jakiś czas by zagłębić się w ten temat. O tyle jest to problematyczne, że przy okazji ruszam Hibernate i na pewno choć podstawy Springa. Do tego dochodzi język Groovy i wszelakie dobrodziejstwa Grailsów (ich własny ORM, własna ‘implementacja’ widoku). Dodam jeszcze, że całość będzie pisana w NetBeans w wersji 6.5, a Grailsy będą w ostatniej stabilnej wersji, czyli oznaczonej numerkiem 1.0.4. Celem zaś jak już mówiłem będzie stworzenie w pełni funkcjonalnej aplikacji internetowej.

PS. Jak postawić sobie środowisko pracy w okienkach jest całkiem przystępnie opisane w necie. Nie żeby to jakoś trudne było, no ale…

luty 16, 2009

Swinguj z nami czyli piszemy aplikację cz.2

Zaszufladkowany do: Eclipse, Java, JavaServerPages, NetBeans, Tomcat — Tagi:, , , — chlebik @ 11:28 pm

Po kilku miesiącach od pierwszego wydania przyszła kolej na krok dalej – oto druga wersja klienta do gry w Arkadię, opartego na Swingu i mojej niedostatecznej znajomości Javy :)

Przyznaję, że wydanie to mogłoby pojawić się wcześniej. Jednakże wpierw mały romans z JEE, a potem wypadki losowe odwlekły ten fakt w czasie. Przez kilkanaście ostatnich dni przysiadłem fałdów i oto jest – druga wersja ChlebikClient. Wiele jeszcze jej brakuje do optymalnego funkcjonowania jako wymarzony klient, jednakże widać już pewne zarysy jak mogłaby wyglądać taka aplikacja, kiedy bierze się za nią newbies. Jednakże postanowiłem, że wydanie drugie będzie również i ostatnim – gdyż kolejne wydania byłyby po prostu dokładaniem bardzo podobnych do obecnych cegiełek. Czyli kolejny JInternalFrame, kolejny plik XMLa i tak dalej – ani to wiele już nie rozwija, a i sensowności dalszej w tym nie ma zbyt wiele.

Popracowałem z NetBeansem używając jego pomocy do tworzenia GUI, mam mniej więcej pojęcie o wątkach aplikacji pisanej w Swingu (choć i tak niewiele jak znam życie), operowanie podstawowe na plikach XML, poszczególne komponenty też obejrzałem sobie z kilku stron. Na dzień dzisiejszy dalsze prace zostają wstrzymane i odłożone na czasy obfitujące w wolny czas (może kiedyś nadejdą). Póki co zapraszam na podstronę projektu, gdzie można przeczytać listę zmian oraz ściągnąć najnowszą wersję.

Co zaś do przyszłości – zmierzam w kierunku JEE. Dla nauki rozpoczynam pisanie aplikacji internetowej. Wstępnie technologie użyte to JSP, Hibernate/JDBC, wszystko zapakowane w Tomcata. Być może tym razem spróbuję użyć do pracy Eclipse’a wraz z jego rozszerzeniem WTP.

styczeń 21, 2009

GridBagLayout w akcji

Zaszufladkowany do: Java, NetBeans — chlebik @ 12:03 am

Do tej pory w ChlebikClient wywoływane były zdarzenia oparte na pokazywaniu kolejnych okien JPane. Główna zaś ramka aplikacji została ‘narysowana’ w NetBeans. Kiedy zatem przyszła pora na stworzenie wewnętrznego okna z możliwością wyboru kolorów zaczęło się robić ciekawie, a konkretniej rzecz w zabawie z ułożeniem elementów wewnątrz ramki.

Do pozycjonowania elementów na kolejnych oknach aplikacji używane są tzw. layout managery. Zgodnie z nazwą zawiadują one rozmieszczeniem poszczególnych elementów – w zależności od potrzeb, używać można jednego z zaimplementowanych w Swingu. Co więcej, można nawet użyć IDE do ‘narysowania’ takiego okienka. Zaintrygował mnie jednak fragment ‘Thinking in Java’, gdzie autor napisał, że menadżer GridBagLayout jest bardzo trudny, ale daje też sporo możliwości. Stwierdziłem zatem, że na prostym przykładzie przećwiczę ten element, skoro niby jest trudny, to tym większa radocha z jego poznania.

Oto wstępny kod (bez importów i takich tam):

JFrame okienko = new JFrame("Testowe okienko");
GridBagLayout layout = new GridBagLayout();

okienko.setLayout(layout);
okienko.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
okienko.setSize(250, 250);
okienko.setLocation(400, 400);
okienko.setVisible(true);

Wyjaśniać za wiele raczej nie trzeba. Tworzymy sobie ramkę – w aplikacji byłaby to instancja klasy JInternalFrame, ale jako, że to jest nasze jedyne okienko to musi ucieleśniać ‘klasę wyżej’ w hierarchii kontenerów. Domyślnie kończymy działanie aplikacji po zamknięciu ramki, ustawiamy jej wymiary i położenie. Należy zwrócić uwagę, że tworzymy już obiekt GridBagLayout, choć na razie z braku elementów wewnątrz ramki niewiele z tego wynika.

Naszym celem jest stworzenie prostego wybierania kolorów. Każdy element aplikacji może mieć przypisany inny kolor niż domyślny. Dlatego też wylistujemy dostępne opcjew takiej formie:

JLabel (nazwa) JLabel (pusta, tylko tło z kolorem) JButton (przycisk zmień)

W ten sposób wypełnimy całą ramkę. Do pracy!

Przy dodawaniu elementów do kontenera, którym zawiaduje GridBagLayout, możemy przypisać do każdego takiego elementu obiekt GridBagConstraints, który odpowiednio ustawi dany element w kontenerze. Cała idea tego menadżera layoutu polega na podzieleniu całego kontenera na ‘komórki’, w które wkładamy następnie elementy. Przypomina to budowanie stron WWW w oparciu o tabelki i zasadniczo porównanie jest dość trafne, z tym tylko, że daje o wiele więcej możliwości ustawienia położenia.

Jak pokazałem powyżej, zależało mi na 3 kolumnach, w których umieściłbym elementy JLabel i JButton. Oczywiście powinny być one wyrównane oraz posiadać dokładnie te same wymiary. Do kodu dodałem wywołanie metody pack(), która rozszerza kontener do zadanych rozmiarów, a kiedy ich nie ma – do rozmiaru odpowiedniego, aby zmieściły się w nim wszystkie elementy (i jednocześnie były widoczne). Zatem możemy zakomentować linijkę określającą rozmiar naszej ramki, a komponenty wewnątrz niej rozepchają ją do odpowiednich rozmiarów.

Tworzymy obiekt GridBagConstraints i następnie przypisujemy jego właściwości insets odpowiedni obiekt, który określa ‘oddalenie’ danego elementu od krawędzi ‘komórki’. Komórki, gdyż następnymi własnościami obiektu GridBagConstraintsgridx i gridy. One określają w której komórce ma znaleźć się wskazany element – numeracja zaczyna się w obu przypadkach od 0 i oznacza górny lewy róg ramki. Kiedy mamy już tak określony obiekt, tworzymy nową etykietę i dodajemy ją do istniejącej ramki (poprzez metodę add kontenera). Oto zatem fragment kodu:

GridBagConstraints ogranicznik = new GridBagConstraints();
ogranicznik.insets = new Insets(5, 10, 5, 5);
ogranicznik.gridx = 0;
ogranicznik.gridy = 0;

JLabel kolor1name = new JLabel("kolor1");
kolor1name.setBorder(javax.swing.BorderFactory.createLineBorder(Color.BLUE, 1));
okienko.add(kolor1name, ogranicznik);

okienko.pack();

Dodam tylko, że parametry konstruktora obiektu Insets oznaczają kolejno górę, lewo, dół i prawo (czyli odwrotnie niż w przypadku CSSa). Do etykiety dodałem też ramkę, aby było dobrze widać efekty naszych poczynań.

1kolor

Ramka została utworzona w taki oto sposób (głównie chodzi o szerokość), aby zmieścić podstawowe elementy górnej belki (ikonkę, część tytułu, przyciski), a w środku mamy naszą etykietę. Wygląda to jednakże niezaszczególnie zatem dopiszmy do kodu dalszą część:

ogranicznik.gridx = 1;
JLabel kolor1bg = new JLabel("kolor1tło");
kolor1bg.setBorder(javax.swing.BorderFactory.createLineBorder(Color.RED, 1));
okienko.add(kolor1bg, ogranicznik);

ogranicznik.gridx = 2;
JButton kolor1zmien = new JButton("Zmień");
okienko.add(kolor1zmien, ogranicznik);

I tak to oto powinno wyglądać:

2kolor

Jak widać przy dodawaniu kolejnych elementów zmieniam tylko wartość własności gridx, co powoduje rozciąganie całej ramki, gdyż powiększa się ilość komórek ‘w poziomie’. Dodajmy teraz drugi wiersz takich samych elementów – wystarczy skopiować kod zmieniając nazwy obiektów i modyfikując na początek wartość gridy na 1. Oto efekt:

3kolor

Na zakończenie omówimy jeszcze jedną rzecz – położenie elementu w konkretnej ‘komórce’. Otóż w obiekcie GridBagConstraints mamy statyczne zmienne, które określają położenie elementu. Jeśli zatem chcemy, aby np. nasza etykieta kolor1 znalazła się w górnym-lewym rogu swej komórki, wówczas w obiekcie GridBagConstraints modyfikujemy własność anchor na GridBagConstraints.NORTHWEST i efekt gotowy! Oczywiście wtedy ustawiamy właśność insets na wartości domyślne (0,0,0,0). Tak to wygląda po uruchomieniu:

4kolor

Jak zatem widać nie taki diabeł straszny jak go malują. Oczywiście to taki mały przedsmak – polecam zapoznanie się z dokumentacją, która z pewnością pokaże jeszcze masę możliwości związanych z tym menadżerem layoutu. Jak to mówią – Position is everything :)

grudzień 2, 2008

TDD czyli programowanie sterowane testami

Zaszufladkowany do: Java, NetBeans — Tagi:, , , — chlebik @ 1:18 am

Każdy kto w programistycznych kręgach obraca się pewien czas, prędzej lub później natknął się na pojęcie Test driven development/programming. Jest to tzw. programowanie sterowane testami – metodologia (metoda?) programowania opierająca się na idei, iż przed napisaniem kodu należy utworzyć stosowne testy, które umożliwią sprawdzenie działania kodu, który dopiero zamierzamy napisać. Zatem jajko czy kura?

Po więcej szczegółów zapraszam do wikipedii. Metoda ta potrafi być naprawdę przydatna i pozwala na pisanie lepszego kodu, a także na sprawniejsze nim zarządzanie. W tym wpisie zaprezentuję wzięty z życia przykład TDD, a także mini-HOWTO szkieletu JUnit NetBeans. Zatem do dzieła.

Do napisania jest kawałek kodu, którego celem jest:

- otworzenie pliku tekstowego

- wgranie jego zawartości do zmiennej

- wyświetlenie zawartości na ekran

Rzecz prosta i zasadniczo głównie to, co może się zakończyć niepowodzeniem to pierwszy punkt, co zresztą implikuje powodzenie lub niepowodzenie działań z punktów kolejnych. Mamy taką listę rzeczy do zrobienia, zatem przed napisaniem kodu zastanówmy się co może pójść nie tak:

- plik może nie istnieć

- możemy nie mieć uprawnień do jego odczytu

- plik może okazać się po prostu pusty

- wczytanie z pliku może zakończyć się niepowodzeniem

W naszym projekcie klasy realizującej odczyt z pliku dzięki powyższej liście rysuje się wygląd poszczególnych metod, choć w zasadzie to potrzebujemy raptem jedną :)  Możnaby stworzyć kilka metod, które wykonywałyby się jedna po drugiej, uzależniając swe wykonanie od powodzenia poprzedniej. Czyli mielibyśmy jakieś fileExists(), potem pewnie isReadable(), zaś na końcu ReadFile() i być może jeszcze fileClose(). Kilka z tych metod zaimplementujemy.

Najbardziej popularnym szkieletem (frameworkiem) używanym do przeprowadzania testów jednostkowych, jest JUnit. Standardowo jest on dodawany do NetBeans, zatem stworzenie testów dla projektu tworzonego w tym IDE jest naprawdę szybkie i bezbolesne. W saym JUnit wszystkie klasy testujące inne klasy, muszą dziedziczyć po klasie TestCase z tegoż frameworka (to dla wersji 3.x). NetBeans umożliwia automatyczne wygenerowanie testów dla już istniejącej klasy w zaledwie kilka chwil. Tutaj mała uwaga. Istnieją różnice między kolejnymi wersjami JUnitNetBeans w wersji 6.1, na której pracuję dawał możliwość wyboru pomiędzy stylami 3.x i 4.x.  Różnica jest zasadniczo dość istotna – w wersji 3.x każda klasa testująca musi dziedziczyć swoją funkcjonalność po klasie TestUnit, a także trzymać się konwencji nazewniczych (dodawania suffixu -Test do nazwy każdej metody). W wersji 4.x wykorzystywany jest mechanizm asercji , więcej na temat różnic pomiędzy wersją 3.x, a 4.x można znaleźć tutaj.

Wiadomo już zatem o co mniej więcej się rozchodzi. Napiszmy zatem klasę, która zawiera interesujące nas metody:

public class ChlebikConfigChangelog {

private StringBuilder content = new StringBuilder();
private FileReader filereader;

public void loadFile(String fileName) throws FileNotFoundException
{
filereader = new FileReader(fileName);
}

public String readFile() throws IOException
{

String s;
BufferedReader br = new BufferedReader(filereader);

while((s = br.readLine()) != null)
{
System.out.println(s);
content.append(s + "\n");
}
filereader.close();

if( content.length() > 0 )
{
return content.toString();
}
else
{
throw new IOException();
}

}

}

Kod jest prosty jak konstrukcja gwoździa. Konstruktor ma za zadanie otworzyc plik poprzez stworzenie obiektu FileReader. Jeśli plik nie istnieje metoda fileExists wyrzuca wyjątek. Mamy też metodę ReadFile, która przechodzi po pliku i wczytuje do zmiennej jego treść, po czym zwraca ten łańcuch, albo też wyrzuca wyjątek jeśli okazało się, że plik był pusty. Oczywiście napisaliśmy wpierw kod, a dopiero teraz stworzymy dla niego testy. Powinno się to odbywać zasadniczo w drugą stronę, ale pragnę pokazać to na jaskrawym przykładzie. Samego pisania testów przed programowaniem trzeba się nauczyć samemu poprzez praktykę.

Testy w NetBeans tworzy się bardzo łatwo. Wystarczy kliknąć prawym przyciskiem na wybranej klasie, wybrać Tools i Create JUnit Test. Wypada zapoznać się z możliwymi opcjami generowania klasy testującej. U mnie takowa wygląda po utworzeniu następująco:

public class ChlebikConfigChangelogTest {

public ChlebikConfigChangelogTest() {
}

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Test
public void testLoadFile() throws Exception {
System.out.println("loadFile");
String fileName = "";
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
instance.loadFile(fileName);
fail("The test case is a prototype.");
}

@Test
public void testReadFile() throws Exception {
System.out.println("readFile");
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
String expResult = "";
String result = instance.readFile();
assertEquals(expResult, result);
fail("The test case is a prototype.");
}

}

I teraz do ciała każdej z metod testujących należy wrzucić kod, który przetestuje metodę. By należycie przetestować metodę readFile można zaproponować taki oto kod (modyfikując ten wygenerowany automatycznie):

@Test
public void testReadFile() throws Exception {

ChlebikConfigChangelog instance = new ChlebikConfigChangelog();

// Jesli tresc pliku to 'test'
instance.loadFile("test.txt");
String result = instance.readFile();
assertEquals("test", result);

}

@Test(expected=IOException.class)
public void testEmptyReadFile() throws IOException {

// Jesli tresc pliku nie istnieje (jest pusta)
System.out.println("readFile");
ChlebikConfigChangelog instance = new ChlebikConfigChangelog();
instance.loadFile("/test2.txt");
String result = instance.readFile();
}

Ta druga metoda służy do badania wyrzucanych wyjątków. Zastosowanie asercji @Test(excepcted=tunazwaklasywyjatku.class) buduje test (metodę), której wywołanie niezakończone wyrzuceniem wyjątku będzie uznawane za porażkę testu. Jest to bardzo użyteczny sposób na ich testowanie.

Mam nadzieję, że ten krótki przykład da podstawowe pojęcie o testach jednostkowych i TDD. Jak już wcześniej wspomniałem by w pełni wykorzystać zalety tego podejścia należy robić jedną rzecz – testować, testować, testować, a wówczas TDD stanie się naturalną drogą tworzenia oprogramowania.

listopad 27, 2008

JTextPane w akcji

Zaszufladkowany do: Java, NetBeans — Tagi:, , , — chlebik @ 12:46 am

Jak wspomniałem w jednym z poprzednich wpisów, pamiętam jeszcze czasy Visual Basica bodajże w wersji 4.0 i do dziś mam przed oczami widok pięknie układających się na ekranie elementów. Oczywiście było to śliczne w porównaniu do toporych interfejsów graficznych implementowanych w Turbo Pascalu. W NetBeans na początku wyglądało to dość podobnie. Byłem również święcie przekonany, że tak prozaiczna rzecz jak dodanie do komponenetu tekstowego odpowiednio sformatowanego tekstu nie jest problemem. Jak zazwyczaj ostatnio – myliłem się.

Omyłka jednakże wręcz mnie zdziwiła. Gdybym bowiem w polu tekstowym Swinga chciał odpalić animację flasha z bajerami porażka byłaby dość zrozumiała. W przypadku jednakże JTextPane, troszeczkę zwątpiłem. Dla porządku wykładu:

- podstawowym komponentem tekstowym w Swingu jest JTextField, który to umożliwia edycję i wyświetlanie jednego wiesza tekstu.

- drugim komponentem jest JTextArea. Box ten umożliwia wyświetlanie w oknie wielu linii tekstu, do tego można je edytować. Jedynym ograniczeniem jest fakt, iż JTextArea wyświetla czysty tekst – bez jakichkolwiek wodotrysków.

- nie napisałem o JLabel, ale to zgodnie z nazwą pewna wizytówka innego komponenetu (przynajmniej ja ją tak traktuję), zatem za pełnowymiarowy komponent tekstowy jej nie uważam.

- i na koniec mamy JTextPane, a także klasę wobec niej nadrzędną - JEditorPane. Ja jednakże skupię się na tej pierwszej, gdyż do niej mamy dostęp w palecie NetBeans i to z tym komponentem starałem się coś zrobić.

JTextPane ma w zamyśle umożliwiać wyświetlenie komponenetu tekstowego w aplikacji, wraz ze specjalnie formatowanym tekstem. Moje wymagania na początek nie były jakoś rozbudowane. Mianowicie chodziło mi o pole informacyjne ( metoda JOptionPane.showMessageDialog ), które zawierałoby komponent z ładnie sformatowanymi danymi. Konkretnie chodziło mi o:

- wycentrowanie tekstu

- odpowiedni kolor backgroundu

- margines pomiędzy granicą komponentu, a tekstem (coś a la CSSowy padding).

Nie są to specjalnie wygórowane żądania trzeba przyznać. Jednakże Swing skutecznie się postarał by to wszystko zamotać. Być może moje oczekiwania w stosunku do IDE są zbyt duże i zasadniczo jest dobrze tak jak jest. Nie bardzo mnie to jednakże przekonuje, dlaczego tak prozaiczną rzecz jak ustalenie kilku stylów muszę realizować kodowo odwołując się do 4 różnych obiektów? Oto kod:

JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
MutableAttributeSet standard = new SimpleAttributeSet();

StyleConstants.setAlignment(standard, StyleConstants.ALIGN_CENTER);
StyleConstants.setLeftIndent(standard, 40);
StyleConstants.setRightIndent(standard, 40);

Color szary = new Color(224, 226, 235);
doc.setParagraphAttributes(0, 0, standard, true);
textPane.setBackground(szary);
textPane.setBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true));

Tyle potrzeba pisaniny (ok, da się to pewnie skrócić o linijkę czy dwie wrzucając wywołania nowych obiektów w parametry metod). A nie możnaby zrobić tego w formie D&D prosto w IDE? Niestety nie dało się i dlatego trzeba się bawić z kodem. Nota bene dość ciekawym i mam nadzieję, że jego forma da wszystkim impuls do daleszego poszukiwania wiedzy na temat przyozdabiania komponentów.

październik 6, 2008

Asercje i testowanie kodu

Zaszufladkowany do: Java, NetBeans — Tagi:, , — chlebik @ 12:42 am

Wiadomym jest, że codzienna praktyka kodera PHP polega bardzo często na napisaniu w ciągu dnia kilkanaście  (jeśli nie kilkadziesąt) razy kombinacji różnych alertów, die’ów czy inszych echo celem podejrzenia działania programu w konkretnym momencie, lub też zwracanej wartości. Praktyka codziennego stosowania w pracy testów jednostkowych jakoś się w webdeveloperskim świecie nie do końca przyjęła, a jeśli już, to w formie ostatecznych testów przed wypuszczeniem aplikacji do poważnego użycia (trochę upraszczam, wiem).

W Javie mamy osławiony JUnit, framework do tworzenia testów jednostkowych, o których nota bene książka czeka w kolejce na przeczytanie. Jednakże na szybko należy wspomnieć o innym ciekawym rozwiązaniu, które w praktyce jest dla programistów całkiem miłym ułatwieniem. Konkretnie chodzi o asercje. Mówiąc krótko jest to taki warunek logiczny, którego niespełnienie (fałsz) powoduje przerwanie wykonywania programu. Jest to element języka, zatem nie trzeba od razu zatrudniać całej machiny testów jednostkowych, wystarczy wklepać w kod raptem jedną linijkę. Oto przykład:


public static void main(String[] args) { int licznik = 2;
int dzielnik = 0; // To jest zabronione
int wynik;
assert dzielnik != 0 : "Ty no nie dzieli się przez zero";
wynik = licznik/dzielnik; }

Oczywiście przykład jest bardzo prosty i ostry, w normalnych warunkach bez składni assert wyrzucony zostałby  ArithmeticException. Jednakże w tym przypadku zostanie uprzednio zgłoszony wyjątek AssertionError wraz z komunikatem, który podaliśmy zaraz po warunku. Niby nic, a jednak wiele – jakie są zyski z używania asercji?

Zasadniczo to dwa. Pierwszy jest taki, że wyrzucanie wyjątków asercji jest domyślnie wyłaczone!!! By uruchomić tę opcję należy wywoływać kompilator z parametrem -ea. NetBeans wystarczy kliknąć prawym przyciskiem myszy na projekcie i Set Configuration->customize. I w okienku uruchomieniowym w rubryce VMOptions wpisać owo -ea.  Od tej pory przy kompilacji asercje będą brane pod uwagę. Jest to o tyle dobre, że dzięki jednej opcji, można bez problemu w ciągu jednej chwili przestawić aplikację ze stanu docelowego na developerski. Nie trzeba zakomentowywać masy kodu, wystarczy zmienić argument wywołania VM.

Drugim plusem jest informacja dla innych (poważne projekty to raczej nie domena 1 osoby) o założeniach dotyczących danego fragmentu kodu. Oczywiście na podanym przeze mnie przykładzie tego może i nie widać, za to przy dużych projektach, kiedy zależności między klasami zaczynają przypominać labirynt asercje pokazują swoją przydatność. O wiele łatwiej jest przeczytać w kodzie (lub wyniku kompilacji) “Kierowniku tutaj nie powinno być NULL”, niż przedzierać się przez gąszcz plików w poszukiwaniu klasy, z której pochodzi feralna metoda powodująca wyrzucenie wyjątku. Mała rzecz, a cieszy.

Starsze wpisy »

Blog na WordPress.com.