Category Archives: NetBeans

SVN w Debianie bo ile można nosić kod ze sobą

Posiadanie własnego serwera daje szereg możliwości. Jedną z nich jest jedno miejsce ze wszystkimi usługami, do którego możemy dostać się zewsząd. W przypadku programisty to chyba jego kod jest najbardziej pożądanym dobrem – zatem jego dostępność jest sprawą nie do przecenienia.

By nie komplikować za bardzo postanowiłem postawić repozytorium SVN – bardzo popularnego systemu kontroli wersji, dobrze obsługiwanego zarówno pod Windowsem jak i linuxem. W związku z tym, iż pracuję na tych dwóch systemach możliwość łatwej obsługi jest dla mnie szczególnie istotna. Zatem w konsoli klepiemy:

sudo apt-get install subversion

I po chwili możemy cieszyć się naszym systemem kontroli wersji. Dostęp do niego zapewnimy sobie przez natywny protokół SVN. Teraz musimy umieścić gdzieś nowe zupełnie repozytorium, a także nadać prawa do korzystania z niego. W sumie jestem jedynym użytkownikiem serwera, zatem mógłbym zainstalować repozytorium w swoim katalogu domowym. Jednakże nie jest to dobre rozwiązanie – bezpieczniej byłoby stworzyć oddzielnego użytkownika tylko dla dostępu do repozytorium. Bezpieczniej i w sumie wygodniej. Lecimy zatem:

adduser svn

Automatycznie jest tworzony użytkownik oraz grupa o takiej samej nazwie. Repozytorium zainstalujemy w katalogu domowym usera svn, jednakże to za chwilkę. Należy zastanowić się nad dość istotną rzeczą. Otóż póki co zamierzamy wysłać do repozytorium kod źródłowy, który znajduje się na razie na moim dysku twardym. Czyli nie jest to plik WAR, ani nawet rozpakowane na serwerze pliki – muskmy wrzucić całość projektu Netbeans, który mamy u nas na serwerze. Zasadniczo byłoby najwygodniej po prostu przekopiować zawartość katalogu z projektem na serwer, ale trochę to takie… nieeleganckie 🙂 Zresztą jak się okazuje, nasze IDE z taką sytuacją upora się dość szybko i łatwo.

W katalogu usera svn tworzymy katalog, w którym będziemy trzymać nasz kod.


mkdir repos
cd repos
mkdir programbash
svnadmin create /home/svn/repos/programbash

Rzecz jasna najlepiej tego typu zabiegi dokonywać kiedy jesteśmy zalogowani jako użytkownik user. W przeciwnym razie czeka nas rekursywne nadanie uprawnień do katalogu repos/programbash właśnie temu użytkownikowi. Kiedy mamy katalog, który docelowo ma trzymać nasze (tutaj konkretne dla projektu) repozytorium należałoby je skonfigurować. Przechodzimy do naszego utworzonego repozytorium i zaglądamy do katalogu conf. Należy poddać edycji plik conf/svnserver.conf:

anon-access = none # tylko zalogowani userzy moga laczyc sie z repo
auth-access = write # userzy moga szalec
password-db = passwd # czyli dostep dla par user-haslo

Zgodnie z ostatnim zapisem w tym pliku poddajemy teraz edycji plik passwd w tym samym katalogu:

[svn] = [nasze_tajne_haslo]

I tyle konfiguracji. Należy omówić teraz budowę repozytorium – głównym jego katalogiem jest trunk, gdzie leży główna część naszego kodu. Do tego elementami repozytorium SVN są katalogi branches oraz tags. Przynajmniej taką strukturę zaleca nam dokumentacja SVNa i akurat tutaj zgódźmy się na takie rozwiązanie. Jednakże katalogi te nie są tworzone automatycznie przez SVNa zatem musimy dodać je sami. By to osiągnąć należy przejść do katalogu /tmp (wybrałem go tylko dlatego, że na pewno jest tam dostęp i potem będziemy mogli jego zawartość wyczyścić) i wydać takie polecenie:

svn co file:///home/svn/repos/programbash

I powinniśmy otrzymać następujący komunikat:

Checked out revision 0.

Konkretnie w tej chwili stworzyliśmy obraz repozytorium w wybranej przez nas lokalizacji. Dzięki temu na spokojnie dodamy wskazane katalogi:

mkdir trunk
mkdir tags
mkdir branches
svn add trunk
svn add tags
svn add branches

W ten sposób utworzone katalogi zostały wybrane do włączenia ich do systemu kontroli wersji. Teraz wypadałoby je do niego wysłać:

svn commit -m "Pierwszy commit - dodanie katalogow repozytorium"

I możemy sobie obejrzeć efekt:

Adding branches
Adding tags
Adding trunkCommitted revision 1.

Nasz pierwszy commit zakończył się powodzeniem (katalog w /tmp możemy usunąć). W naszym repozytorium istnieje już odpowiednia struktura katalogów i czeka na wypełnienie treścią. By to osiągnąć musimy udostępnić nasze repozytorium na zewnątrz. Istnieje kilka możliwości – udostępnianie poprzez protokół HTTP (do tego potrzebne jest dokonfigurowanie serwera WWW), posługiwanie się protokołem SSH (również konfiguracja), albo też natywnym protokołem dla SVN i to rozwiązanie zastosujemy. Za komunikację po ww. protokole odpowiada demon (program może być uruchomiony jako demon) o nazwie svnserve. Jest on automatycznie instalowany wraz z SVN, zatem nie trzeba instalować nic dodatkowego. Demon ten nasłuchuje domyślnie na porcie 3690. Uruchamiamy go w ten sposób:

svnserve -d -r /home/svn/repos

Wskazujemy, że działamy jako demon (-d), a także wskazujemy na roboczy katalog. Dzięki wskazaniu na repos nasz demon obsłuży wszystkie repozytoria jakie kiedykolwiek przyjdzie nam do głowy dodać. Rzecz jasna przydałoby się dodać uruchamianie tego demona przy starcie systemu poprzez edycję skryptów startowych. Na razie jednakże skupmy się na zaimportowaniu plików do repozytorium. Uruchamiamy Netbeans (zakładam, że pluginy do obsługi SVN zostały zainstalowane) i klikamy prawym przyciskiem myszy na projekcie, który zamierzamy wysłać do repozytorium, po czym wybieramy Versioning -> Import into Subversion repository tak jak poniżej:

W pojawiąjacym się okienku wpisujemy:

svn://chlebik.pl/programbash/trunk

Wpisujemy też rzecz jasna użytkownika i hasło po czym klikamy na Next i następuje (powinno 🙂 połączenie z serwerem. Przy naszej strukturze repozytorium (każdy projekt będzie posiadał oddzielny katalog) katalog trunk jest głównym, zatem to właśnie jego wskazujemy jako cel importu. Musimy również wpisać komunikat związany z tym importem i klikamy Next.

Po chwili powinniśmy zobaczyć taki ekran:

I ostatecznie nacisnąć na przycisk Finish. Akurat Programbash trochę waży, zatem w zależności od szybkości łącza internetowego wysłanie wszystkich plików na serwer może trochę potrwać. Ostatecznie w zakładce Output otrzymałem taki komunikat:

Transmitting file data ...
Committed revision 2.
update D:/Java/programbash2 -r HEAD --depth=files --force
At revision 2.
==[IDE]== 2010-02-15 01:14:21 Committing... finished.

Czyli zasadniczo wszystko OK. Sprawdźmy czy wszystko jest na pewno w porządku. Użyłem do tego Eclipse, aby nie mieszać w Netbeans. Odpalamy IDE, tworzymy nowy projekt, wybieramy jako typ SVN -> Checkout project , dodajemy nową lokację repozytorium, podajemy stosowne dane i Eclipse uruchamia kreatora projektu. Zakładam rzecz jasna, że nasz Eclipse posiada plugin do obsługi SVNa – polecam Subclipse. U mnie projekt zaimportował się bez najmniejszych przeszkód i tym samym dowiodłem, że repozytorium działa 🙂

Rzecz na koniec dość istotna – do repozytorium dodałem z premedytacją pliki projektu Netbeans. Standardowo nie robi się tego w ten sposób – jakiekolwiek szczegóły deploymentu aplikacji powinny zostać pominięte w repozytorium. Dzięki temu nie śmiecimy w nim plikami potencjalnie różnymi u każdego programisty. Jednakże zasady tutaj panujące powinny być uzgodnione przez użytkowników repozytorium. W tym przypadku ja będę jedynym, zatem pozwoliłem sobie na taką małą frywolność 🙂

Upgrade NetBeans i co z tego wynikło

Pojawiła się kolejna wersja IDE Netbeans. Jak to zawsze bywa – bardzo lubię updatować swój soft, zatem nie zastanawiałem się długo nad tym faktem. I obiecuję – to już ostatni raz.

Sam proces przebiega bezboleśnie. Wszystko się ściąga, instaluje, po uruchomieniu wita nas fajny screen i ogólnie cud marzenie. Problemy zaczęły się przy skanowaniu projektów. ZONK. W przypadku HowToJava problemów nie było. Wszystko działa. Problemem okazał się ProgramBash, który wpadł w spiralę rzekomych braków bibliotek. Pomimo spędzenia dobrych kilku dni na szukaniu pomocy u wujka Google, nie udało mi się rozwiązać problemu – nagle dziwnym trafem wyparowały zależności i pliki bibliotek, które w wersji 6.8 po prostu wyleciały z dostępnych. Nie wiem na ile to moja wina i brak porządku w bibliotekach i ich wspieraniu, ale dlaczego IDE cokolwiek brzydko się zachowało (jakieś powiadomienie, że biblioteki stare zostaną zmienione/usunięte by się przydało)?

Ostatecznie zatem musiałem utworzyć nowy projekt i ręcznie przepinać kod źródłowy. Przynajmniej osiągnąłem tyle, że ProgramBash będzie powstawał dalej na JSF w wersji 2. Zostawiłem poprzednią wersję Hibernate i wszystkich innych używanych bibliotek. Co prawda dalej przy lokalnym starcie Glassfisha dostaję jakieś zapomniane błędy, ale póki co aplikacja wydaje się działać. Choć co prawda dodawany upload plików na razie wysypał mi błędami (brak UploadFilter, gdyż sypał mi Class not found), mam nadzieję, że niedługo przyjdzie czas na kolejny wpis poświęcony tej aplikacji.

Grailsujemy z bazą, czyli tworzymy linki cz.1

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.

Konfiguracja Grails

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.

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

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

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.

Grailsujemy

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…