Monthly Archives: March 2010

Komunikat dnia

Będąc zalogowany jako ROOT w konsoli wydałem komendę poprzedzoną ‘sudo’, efekt poniżej:

“Root is not in the sudoers file. This incident will be reported.”

Advertisements

Mavenizujemy projekt i dlaczego wyszło jak zawsze

Nie tak dawno pisałem o przygotowaniach do pisania nowej aplikacji. By odpocząć trochę po niechlubnych przygodach z JSF zabrałem się za stawianie infrastruktury dla nowego projektu. Do Springa dołączył Maven.

Co to jest Maven? W odróżnieniu od Anta jest postrzegany nie tylko jako narzędzie, które zawiaduje budowaniem aplikacji javowych, ale też umożliwia szereg innych rzeczy, jak choćby generowanie eleganckiej dokumentacji technicznej. Piszę te słowa za mądrymi książkami – w swojej karierze na razie wystarczał mi Ant i jego zadania stworzone przez NetBeansa w ramach tworzenia projektu. Jednaże trzeba się rozwijać i stąd chęć poznania głównego konkurenta Anta. W konkurencji siła.

Rzecz jasna wpierw wypadałoby zainstalować stosowną wtyczkę. W tym celu udajemy się na stronę http://m2eclipse.sonatype.org/installing-m2eclipse.html, gdzie znajdziemy wszystkie potrzebne informacje. Kiedy już zainstalujemy wtyczkę wypadałoby zabrać się za zainstalowanie samego Mavena. Rzecz wygląda tak, iż wraz z wtyczką dostajemy również i Mavena, ale jak piszą ludzie od NetBeansa najczęściej jest to ‘preview version’, czyli jakieś alfy zmieszane z betą, zatem od biedy można tego użyć, ale lepiej zainstalować stabilną wersję. Wypada zatem odwiedzić stronę Mavena i zaopatrzyć się w najnowszą wersję. Kiedy ją zainstalujemy trzeba wskazać pluginowi naszego IDE katalog z instalacją. Tools->Options->Maven i w polu External Maven Home umieszczamy katalog gdzie zainstalowaliśmy Mavena. Na razie to tyle.

O samym narzędziu możnaby mówić wiele. Od Anta różni się tym, że stosuje ‘podejście deklaratywne’, czyli mówią krótko wpisujemy co chcemy osiągnąć, a Maven to mieli. Myślę, że przykład powie więcej niż moja mozolna dłubanina. Siłą Mavena jest konwencja – wspólne cechy każdego projektu realizowanego z jego udziałem. Co więcej – podążając tropem konwencji – powstały przygotowane tzw. archetypy. Są to przygotowane zawczasu szkielety projektu. W moim przypadku tworzę projekt z udziałem Hibernate i Springa, zatem wypadało szukać takowego. New->Project->Maven->Maven Project. Pojawi się taka oto lista:

Rozwijamy ją – ja wybrałem konkretnie zakładkę Default Archetype Catalog i dalej AppFuse archetype for creating web application with Hibernate, Spring and Spring MVC. Klikamy Next i dostajemy takie okno:

Myślę, że widać rubryki i to, co w nie wpisałem. Klikamy Finish i możemy cieszyć się nowiutkim projektem. Upppppsss. Coś nie tak. Dostałem komunikat o tym, iż niemożliwym jest utworzenie projektu, gdyż podany artefakt nie jest archetypem. No świetnie się zaczyna. Ale nie daję się.

Tutorial Springa opisuje jak to wszystko postawić po kolei. No dobra, będzie oldskulowo – konsola rządzi. Na razie jednakże by wpis nie poszedł na marne próbuję osiągnąć cokolwiek z pomocą Mavena. Czyli znów New Project->Maven->Maven Web Application. Wpisujemy to, co tam potrzeba, klikamy Finish.

Scanning for projects…
Setting property: classpath.resource.loader.class => ‘org.codehaus.plexus.velocity.ContextClassLoaderResourceLoader’.
Setting property: velocimacro.messages.on => ‘false’.
Setting property: resource.loader => ‘classpath’.
Setting property: resource.manager.logwhenfound => ‘false’.
[archetype:generate]
Generating project in Batch mode
[WARN]No archetype repository found. Falling back to central repository (http://repo1.maven.org/maven2).
[WARN]Use -DarchetypeRepository= if archetype’s repository is elsewhere.
————————————————————————
BUILD SUCCESSFUL
————————————————————————
Total time: 4 seconds
Finished at: Tue Mar 30 00:20:25 CEST 2010
Final Memory: 138M/275M
————————————————————————

Mamy progres. Pojawiła się gotowa struktura projektu. Z ciekawości prawy przycisk – Run i kolejny ZONK. NetBeans pyta się o serwer, na którym mam to uruchomić. Problem w tym, że nie listuje przy okazji żadnego z nich, a przecież Tomcat i Glassfish leżą sobie spokojnie na dysku. Po kolejnym kwadransie grzebania wyszło mi, że przy tworzeniu projektu nie mogę zaznaczyć Java EE 6, gdyż powoduje to takie właśnie problemy. Zaznaczenie wersji 5 pomaga i można sobie uruchomić szkielet programu (do Springa to jednakże jest daleko). Wyskakuje “Hello World” i chyba powinienem być zadowolony. Nie jestem. Na pewno przy Mavenie pozostanę, wszak nauczyć się chciałem czegoś nowego, ale czy to normalne, że zwykły programer jak ja ma z tak podstawowymi rzeczami problemy? Czy ja naprawdę coś robię źle?

PS. Odpaliłem projekt Spring+Hibernate poprzez standardowy generator NetBeansJava Web->Web Application. Wybrałem frameworki, określiłem serwer i nazwę i oto Ant zamielił i po 10 sekundach miałem śliczny projekt, działający, z podpiętymi bibliotekami i szczerzący się bardziej rozbudowanym “Hello World”. Idę spać, ile można się wkurzać.

Ostateczne dodanie wpisu w ProgramBash

Umilkło ostatnio na blogu, dopadła mnie mądrze pisząc “prokrastynacja”, a po polsku – nie chciało mi się jak cholera.

Jednakże poczucie obowiązku robi swoje – dziś ostatni odcinek w cyklu “dodajemy wpisy w ProgramBash“. Zasadniczo nie za wiele tutaj nowości – widok, walidacja, zapis do bazy. Pozwoliłem sobie nie przeklejać listingów niezbyt różniących się od tych z poprzedniego wpisu dotyczącego ProgramBash. Jedyne co wypada pokazać, to użycie kolejnego komponentu Richafaces, jakim jest komponent DataScroller. Jest to nie mniej i nie więcej, a paginator dla danych, które zamierzamy wyświetlić. Oto kod:

 <h:form id="topForm">

        <rich:datascroller align="left" for="topList" maxPages="20"
             reRender="sc2, topList" id="sc1" oncomplete="SyntaxHighlighter.highlight()" />
     
        <rich:dataTable width="755" id="topList" rows="2" columnClasses="col"
           value="#{entryBean.topList}" var="entry"> 
            
            <f:facet name="header">
                <rich:columnGroup>
                    <h:column>        
                    </h:column>
                </rich:columnGroup>
            </f:facet>

            <h:column>
                Punktów: <h:outputText value="#{entry.points}" /><br />
                Dodał: <h:outputText value="#{entry.author.nick}" /><br />
                W kategorii <strong><h:outputText value="#{entry.category}" /></strong> w dniu: <strong><h:outputText value="#{entry.adddate}" /></strong><br /><br />

                <pre class="brush: <h:outputText value='#{entry.category.shortname}' />">
                    <h:outputFormat value="#{entry.entry}" />
                </pre>


            </h:column>


        </rich:dataTable>
        <rich:datascroller align="left" for="topList" maxPages="20"
          id="sc2" reRender="sc1, topList"  oncomplete="SyntaxHighlighter.highlight()">
        </rich:datascroller>

      
    </h:form>

Umieszczony w odpowiednim widoku komponent ten zaczytuje ze stosownego beana ( entryBean ) wszystkie wpisy posortowane po ilości posiadanych punktów. Jest to o tyle hardkorowe, że w przypadku np. 100k wpisów mielibyśmy spore narzuty na wydajności bazy i całej aplikacji. Jednakże w środowisku produkcyjnym do takich rzeczy standardowo uzywałoby się jakiegoś cache. Na potrzeby edukacyjne nie ma problemu – możemy zostawić to tak jak jest.

Domyślnie zaś ilość wyświetlanych rekordów na stronę to 2 – nie jest to zbyt duża ilość, ale chodziło mi o pokazanie możliwości paginacji bez musu tworzenia testowych 30 wpisów. Na razie pozostanie to wszystko bez zmian. Należy także zwrócić uwagę na podpięcie formatowania kodu – służą do tego znaczniki pre wraz z odpowiednią klasą. Konkretna klasa jest reprezentowana przez nową składową encji EntryCategory – shortname. Uwaga! Należy zwrócić szczególną uwagę na atrybut oncomplete i wywołanie metody SyntaxHighlighter.highlight()! Bez tego po wgraniu nowej strony z kodem nie zostanie on sformatowany!!! Straciłem na to godzinę szukania i kombinowania.

Problem polega na tym, iż na moim lokalnym kompie rozwiązanie powyższe śmiga pięknie. Co więcej – niezależnie od tego, czy do dataScrollera wrzucę bezpośrednio atrybut page, czy też nie. Niezależnie również od tego czy trzymam tę wartość w beanie o zasięgu sesji, czy pojedynczego requestu. Wszystko jest OK. Zaś na VPSie – ZONK! Naciskając przyciski zmieniające stronę, podgląd odpowiedzi serwera wskazuje na to, iż aplikacja otrzymała AJAXem jak najbardziej kolejną stronę wyników. Niestety, nie jest to odzwierciedlane w oknie programu. Grzebię w tym już chyba od tygodnia i nic nie jestem w stanie na to poradzić mimo rozlicznych kombinacji. Jeśli ktoś miałby jakiś pomysł – będę wdzięczny.

Efekt końcowy wygląda mniej więcej tak:

Do tego niestety pomimo najszczerszych chęci przegrałem z SyntaxHighlighterem jeśli chodzi o formatowanie kodu, w którym znajduje się ENTER na końcu pierwszej linii. Dorzuca on sobie kilkanaście spacji na początku linii, co wygląda dziwnie (obrazek powyżej), ale co więcej – nie daje się usunąć choćby JSem!!! Prototype dostarczany razem z Richfaces wyrzuca mi błędami (np. jego funkcja remove oficjalnie nie istnieje), zaś próba podpięcia jQuery pod aplikację kończy się prawie śmiercią kliniczną Richfaces. Trudno, cóż począć.

To tyle na dziś – niewiele w sumie zostało rzeczy, które chciałbym do aplikacyjki dodać – na pewno ocenianie wpisów (AJAX), a także możliwość otrzymania danych poprzez webservice (to tak celem przećwiczenia takowych w Javie). Zatem do następnego razu.

PS. Nie lubię JSF.

Sic transit gloria mundi

Dzisiaj z zupełnie innej beczki. Przepraszam znów za obsuw we wpisach, ale to, co ostatnio się u mnie wyprawia zaczęło przechodzić wszelkie pojęcie.

Sic transit gloria mundi oznacza w całkowicie wolnym i dowolnym mym tłumaczeniu – “Tak przemija chwała świata”. I zgodzę się z tym – przemija, a już w kwestii technologii to na pewno. Zacznę od początku – padł mi w samochodzie akumulator. Zasadniczo wszystko OK, rozumiem, że po miesiącu na siarczystym mrozie mógł odmówić posłuszeństwa. Zamówiłem nowy, podłączyłem, samochód działa. Ale to nie koniec – trzy dni później rozwaliła mi się pralka. Nie żeby coś poważnego (nikogo nie zalałem), ale wypaczył się bęben, w związku z czym jej ewentualna naprawa wyniosłaby w sumie tyle samo co kupienie nowej. Zamówiłem zatem nową pralkę (była sobota). Pełen nadziei w niedzielę rano zasiadłem jak co tydzień do komputera by poczytać przy porannej kawie zaległe newslettery/RSSy i tym podobne treści. Moja idylla trwała raptem dwa łyki czarnego napoju – nagle ekran stał się poszatkowany jak kapusta w listopadzie (dla tych z miasta – wtedy się ją kisi). Restart kompa nie pomógł, wyzerowanie ustawień monitora też nie (w sumie kupiłem go w październiku). Wpadłem na pomysł by podłączyć do monitora swojego netbooka – obraz śliczny. Czyli karta graficzna. Wczoraj kupiłem nową kartę graficzną, wszystko działa, to i klepię ten wpis.

Co w tym strasznego? Możnaby wzruszyć ramionami i powiedzieć, że zdarza się. Tylko czy na pewno? Jakiś czas temu czytałem gdzieś w necie tekst, którego myślą przewodnią była idea, że obecnie sprzęt (jakikolwiek, nawet nie chodzi o komputery) robi się z założeniem, że po okresie gwarancji (ew. gwarancji wydłużonej) może się po prostu rozsypać. I tak patrząc na ostatnie 2 tygodnie przygód z techniką jestem skłonny zgodzić się z tym twierdzeniem. Pamiętam pralkę moich rodziców, którą wystali za czasów PRLu. Przeprała ona kilkadziesiąt ton brudnych pieluch i dziecięcych ubrań. Miała chyba z 15 lat kiedy rodzice wymienili ją na nową. Moja miała niecałe 5 lat!!!. No i dzieci nie mam, piorę przecież 2, może 3 razy w tygodniu i to w sumie zawsze na krótkim programie. WTF?

Karta graficzna przyszła razem z nowym komputerem raptem 3 lata temu! Nie gram w gry zasadniczo, najbardziej zaawansowane obliczenia graficzne u mnie w komputerze mają miejsce, gdy nową tapetę ustawiam 🙂 (naprawdę). I okazuje się, że karta graficzna wtedy całkiem niezła (GeForce 7200) po prostu sobie pada po 3 latach. I tutaj wspominam laptopa mojego ojca, który ostatnio kupił sobie “w teren” (jest geodetą). To chyba ponad 10letni wyrób IBMa. Wiadomo, że leży na nim Windows 95, komórki mają chyba dziś lepsze parametry, ale wciąż działa i to bez większych problemów! No to ja czegoś nie rozumiem. Czegoś naprawdę nie rozumiem. A wy?

PS. Czekam na pralkę, na dostawę mają jeszcze 1,5h. Jak im się zepsuje furgonetka po drodze to chyba zostanę bibliotekarzem.
PS2. Dojechała i nawet działa.

Mały test Facebooka

Jakiś czas temu przezwyciężyłem swoje zawodowe skrzywienie, polegające na braku kont w najpopularniejszych portalach społecznościowych. Zarejestrowałem się na Facebooku.

Dziś postanowiłem uruchomić synchronizację mojego bloga z Facebookiem – po to właśnie powstaje ten wpis – by zobaczyć czy toto w ogóle działa 🙂

Co to jest Spring?

Pytanie może wydać się banalne, ale wcale takowym nie jest. Można szybko odpowiedzieć, iż jest to framework aplikacji dla platformy J2EE. Zgoda, ale nie tylko.

Zacznę jednakże od początku – skąd nagle Spring na blogu? Jak do tej pory nie przyszedł na niego jeszcze czas, choć moment ten nadchodzi. Kończąc pisanie ProgramBash rozpocząłem mały research dotyczący następnego projektu. I co do jednego jestem pewien – powstanie on z użyciem właśnie Springa. Pozostałe biblioteki/frameworki/technologie na razie są niedookreślone – dlatego by odpocząć na chwilkę od kodowania postanowiłem przybliżyć dziś chyba najpopularniejszy obecnie framework w świecie Javy.

Dawno temu, mniej więcej w okolicach roku 2002 tworzenie aplikacji webowych dla Javy było dość nieprzyjemne. Dominującym paradygmatem był EJB 2, a o toporności tego narzędzia do dziś krążą legendy. Powstała wtedy książka “J2EE Design and Development” niejakiego pana Roda Johnsona. Korzystając ze swego doświadczenia napisał w niej co mu się nie podoba w J2EE i co wypadałoby z tym zrobić. W książce pojawił się również kod, którym autor wspomagał swój wywód. Geniuszu chyba potrzeba by z pomocniczego kodu w książce o J2EE powstał Spring w takiej formie w jakiej go dziś znamy. Rzecz jasna trochę to trwało, po drodze również doszło do pewnych przetasowań oraz zmian. Zainteresowanych odsyłam do Wikipedii.

Spring jest narzędziem kompleksowym. Zasadniczo możemy używać tylko jego bazowej funkcjonalności – czyli specyficznego powiązania obiektów w aplikacji zwanym Inversion of Control (w skrócie IoC). W podejściu tym (traktowanym też często jako wzorzec projektowy lub paradygmat tworzenia oprogramowania) przekazuje się sterowanie częścią funkcjonalności na zewnątrz (w sensie poza). I tutaj przykładem jest Dependency Injection czyli wstrzykiwanie zależności. Przy pierwszym poznaniu Springa wygląda to jak wyciąganie obiektów z kapelusza, jednakże po pewnym czasie taki sposób tworzenia kodu staje się tak oczywisty i naturalny, iż trudno przerzucić się na coś innego.

Obok IOC dumnie kroczy inny zawodnik – programowanie aspektowe. Można je scharakteryzować bardzo obrazowo jako delegację pewnych czynności na zewnątrz obiektu, gdzie informację o tym jak i gdzie stosować konkretne czynności możemy sobie oprogramować sami. Podręcznikowym przykładem programowania aspektowego jest np. zapewnienie transakcyjności operacji bankowych. Innymi słowy – wszystkie akcje na koncie bankowym (obciążenie, wpłaty, lokaty) są realizowane przez logikę biznesową, jednakże sprawami występującymi w każdej z tych operacji (np. logowanie i uwierzytelnianie) zajmuje się kod zupełnie z daną logiką biznesową niepowiązany. Chyba trochę zagmatwałem, ale na przykładach w tworzonym projekcie bardzo łatwo da się rzecz wytłumaczyć.

Trzecią rzeczą, która jest cudowna w Springu to w końcu implementacja MVC z prawdziwego zdarzenia. Konkretnie chodzi mi o warstwę kontrolera, gdyż w JSF zasadniczo to nie wyglądało. W przypadku tego frameworka mamy klasy kontrolera, które obsługują nadchodzące requesty i wyświetlają odpowiedź. Po drodze zaś możemy z żądaniem zrobić co się nam podoba – obejrzeć, przetworzyć, zwalidować, zapisać w bazie i potem coś jeszcze wyświetlić. Całość nazywa się niezbyt oryginalnie Spring MVC i bardzo mi się spodobała od samego początku.

Opisałem trzy podstawowe (i moim zdaniem najistotniejsze) rzeczy w bibliotece. Z tego co wyczytałem w sieci, najlepszą książką dotyczącą Springa jest ta pozycja, jak zawsze niezastąpionego wydawnictwo Manning. Tutoriale na sieci są również całkiem niezłe, ale jak zawsze najlepszym będzie ten, który powstanie na blogu 🙂 Stay tuned.