24 lipca 2008

faces-config.xml podzielony z javax.faces.CONFIG_FILES

2 komentarzy
Zgodnie ze specyfikacją JavaServer Faces 1.2 (rozdział 10.4.2 Application Startup Behavior, strona 312) podczas uruchamiania aplikacji webowej korzystającej z JSF implementacja JSF wykonuje następujące kroki konfiguracyjne:
  1. (opcjonalnie) sprawdza istnienie definicji servletu javax.faces.webapp.FacesServlet w deskryptorze wdrożenia i w przypadku jego braku może w tym momencie zakończyć pracę
  2. poszukuje META-INF/faces-config.xml we wszystkich zasobach aplikacji webowej (poprzez odpytanie ServletContext o wszystkie dostępne zasoby, jak pliki jar, czy zawartość WEB-INF/classes) i wczytuje je jako plik konfiguracyjny JSF w odwrotnej kolejności do tej zwróconej przez Thread.getContextClassloader().getResources())
  3. sprawdza istnienie parametru kontekstowego javax.faces.CONFIG_FILES, który jest listą plików konfiguracyjnych oddzielonych przecinkiem, a następnie wczytuje je kolejno
  4. sprawdza istnienie pliku /WEB-INF/faces-config.xml w aplikacji webowej
Efekt kroku 2 można zauważyć w sposobie konfiguracji JBoss Seam, gdzie plik jboss-seam.jar zawiera w sobie plik META-INF/faces-config.xml z następującą konfiguracją:
 <?xml version="1.0"?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">

<factory>
<application-factory>org.jboss.seam.jsf.SeamApplicationFactory</application-factory>
</factory>

<application>
<navigation-handler>org.jboss.seam.jsf.SeamNavigationHandler</navigation-handler>
<view-handler>org.jboss.seam.jsf.SeamViewHandler</view-handler>
<state-manager>org.jboss.seam.jsf.SeamStateManager</state-manager>
<el-resolver>org.jboss.seam.el.SeamELResolver</el-resolver>
<message-bundle>org.jboss.seam.core.SeamResourceBundle</message-bundle>
</application>

<lifecycle>
<phase-listener>org.jboss.seam.jsf.SeamPhaseListener</phase-listener>
</lifecycle>

</faces-config>
gdzie każdy z elementów wpływa na konfigurację naszej aplikacji webowej korzystającej z JBoss Seam (i niewprost z JSF). Przy okazji okazało się, że plik jboss-seam.jar zawiera również plik META-INF/ejb-jar.xml, co określa go również jako moduł EJB.

Najbardziej zaintrygował mnie krok 3, o którym już ktoś mi wcześniej wspominał, jako sposobie na podział rozrastającego się faces-config.xml na mniejsze pliki składowe. Z pewnością zarządzanie mniejszymi plikami jest prostsze, więc możliwość podziału faces-config.xml na mniejsze pliki konfiguracyjne jest wartościową informacją.

Możemy, więc posiadać wiele plików konfiguracyjnych w formacie faces-config.xml, które definiujemy w deskryptorze wdrożenia aplikacji webowej - /WEB-INF/web.xml następująco:
 <?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/produkcyjny-faces-config.xml, /WEB-INF/inny-faces-config.xml</param-value>
</context-param>
</web-app>
Daje to ciekawą możliwość nadpisywania konfiguracji, np. produkcyjnej testową lub podobnie, gdzie poszczególne definicje ziaren zarządzanych JSF w produkcyjny-faces-config.xml są nadpisane przez faces-config.xml w katalogu WEB-INF. Po wykonaniu testów funkcjonalnych można po prostu usunąć plik WEB-INF/faces-config.xml i wdrożyć aplikację na właściwe środowisko testowe.

Pozostaje sprawdzenie, czy taki podział konfiguracji JSF jest wspierany przez środowiska programistyczne. Sprawdziłem NetBeans 6.5 i muszę przyznać, że mam dobrą i złą wiadomość. Zacznę od tej złej - jedynie faces-config.xml jest specjalnie traktowany jako plik konfiguracyjny JSF przez edytor PageFlow (pisałem o nim w NetBeans 6 i jego edytor PageFlow do faces-config.xml). Dobra wiadomość jest taka, że tworząc ziarno zarządzane przez asystenta JSF Managed Bean w polu Configuration File widnieją nasze pliki konfiguracyjne JSF.

Nie obyło się bez zgłoszenia kilku błędów odnośnie wsparcia javax.faces.CONFIG_FILES, jak np. Issue #141444 [65cat] Configuration Files without all javax.faces.CONFIG_FILES, gdzie w Configuration Files jedynie wymieniony jest pierwszy z listy plików w javax.faces.CONFIG_FILES oraz faces-config.xml.

Zastanawiam się, jak szeroko stosowana jest owa funkcjonalność JSF podziału pliku konfiguracyjnego faces-config.xml w projektach. Zdarzyło się u Ciebie? Chętnie zapoznałbym się z powodem takiego podziału - łatwość zarządzania, czy coś więcej?

22 lipca 2008

Enterprise JavaBeans (EJB) w skrócie

4 komentarzy
Dostałem ostatnio pytanie, które bardzo mnie zaskoczyło. Zawsze parłem do przodu z tymi wszystkimi technologicznymi wodotryskami, a tu proszę pytanie o podstawy, które mimo swej prostoty trudno było mi początkowo zebrać w strawną treść:

Studiuje sobie technologie ejb, tak jak mowiles zebym zaczal od tego. Ale gdybys mogl mi wytlumaczyc po co sa te cale ziarenka. Do czego sluza jakie maja zastosowanie gdzie ich sie uzywa i do czego ale nie teoretycznie tylko praktycznie. Wiem na czym to wszystko mniej wiecej polega ale nie rozumiem gdzie dokladnie tego uzywac i jakie to ma najczestsze zastosowanie. Pytanie banalne ale jednakze wpisywalem w google i w wiekszosci przypadkow odpowiedz byla taka ze ejb uzywa sie w aplikacjach biznesowych dzieki ejb programista moze budowac aplikacje jak z buduje sie cos z kockow lego. Ok ale do czego dokladnie. Wytlumacz mi o co to wielkie halo z ejb serwletami. Bylbym wdzieczny gdybys mi to wytlumaczyl jak przyslowiowej krowie na miedzy.

I jak tu podejść do tematu? Najlepiej wskazałbym na kilka pozycji książkowych i oczekiwałbym zapoznania się z nimi. Niektórzy preferują również praktyczne podejście do tematu i po kilku przykładach mają pewne zdanie na temat technologii. Tylko, że źle dobrane przykłady mogą całkowicie położyć technologię i można ją całkowicie zaprzepaścić. Wielokrotnie przysłuchuję się różnym rozmowom technicznym i z wielkim niepokojem wyczuwam próbę przepchnięcia tematu z własnego podwórka bez próby zrozumienia innego spojrzenia. Ilu z nas korzysta ze Springa+Hibernate, a gdyby zapytać dlaczego, zapewne padłaby odpowiedź, bo dobre (bo przecież jak inaczej wielu z nas używałoby tego zestawu?!). Pytania o szczegóły, albo alternatywne rozwiązania zazwyczaj kończą się machnięciem ramionami i końcem przyjemnej rozmowy.

Wracając do tematu Enterprise JavaBeans (w skrócie EJB). Po co nam EJB? Przede wszystkim, aby uprościć budowanie aplikacji rozproszonych z użyciem usług dostarczanych przez kontener EJB (= środowisko uruchomieniowe dla ziaren EJB), jak transakcje, utrwalanie danych, bezpieczeństwo, obsługa wyjątków, budzik, asynchroniczna obsługa komunikatów i Web Services. Wykorzystanie usług zwykle odbywa się deklaratywnie, gdzie za pomocą adnotacji lub deskryptora wdrożenia ejb-jar.xml deklarujemy nasze wymagania odnośnie wykorzystania usług w określony sposób. Właśnie możliwość wykorzystania bardzo zaawansowanych technologicznie usług deklaratywnie powoduje, że EJB znajdują swoje miejsce w architekturach aplikacji korporacyjnych. Bez tej specyfikacji wykorzystanie usług byłoby nieprzenośne i wymagające poznania mechanizmów specyficznych dla danego środowiska (= serwera aplikacyjnego), co wiązałoby się z niezwykle wysokimi kosztami rozwoju i utrzymania aplikacji. Wyobraźmy sobie sytuację, w której osoba znająca się na produkcie X dostarczającym wybrane usługi miałaby przesiąść się na produkt Y. Każdorazowe poznawanie nowych produktów jest bardzo kosztowne, a specyfikacje znacząco je obniżają.

Jakkolwiek czasy EJB 2.1 mamy za sobą, to właśnie bolączki z nią związane dały się odczuć wielu, co pchnęło Roda ze SpringSource do stworzenia Spring Framework. Wiele z rozwiązań springowych znalazły swoje miejsce w EJB 3.0 - obecnie ostatniej produkcyjnie wersji specyfikacji EJB.

Wyróżniamy cztery rodzaje ziaren EJB:
  • ziarna sesyjne (ang. session beans), w których można wyróżnić:
    • bezstanowe ziarna sesyjne (ang. stateless session beans, w skrócie SLSB) reprezentujące agentów w aplikacji korporacyjnej, bez utrzymywania stanu ostatnich użyć, np. Sklepikarz
    • stanowe ziarna sesyjne (ang. stateful session beans, w skrócie SFSB) różniące się od SLSB utrzymywaniem stanu między wywołaniami, co czyni jest idealnymi do modelowania bytów trzymających zapis operacji, np. Koszyk, do którego wkładamy towary
  • ziarna komunikacyjne (ziarna sterowane komunikatami, ang. message-driven beans, w skrócie MDB) umożliwiające obsługę komunikacji asynchronicznej, bez nakładania na klienta oczekiwania zakończenia ich pracy, np. DziennikZdarzen
  • encje (ang. entities) modelujące byty trwałe zapisywane do relacyjnej bazy danych, np. Osoba
A teraz pora na przykład wprowadzający w tematykę EJB3. Przyjrzyjmy się klasie pl.jaceklaskowski.ejb3.Sklepikarz (nazwa przypadkowa):
 package pl.jaceklaskowski.ejb3;

interface Sklepikarz {
public void otworzSklep();
}

public class SklepikarzWykwalifikowany implements Sklepikarz {

public void otworzSklep() {
// wykonaj swoją pracę
}

}
Z punktu widzenia programisty Javy nie jest to żadna nadzwyczajna klasa. Ot klasa jak wiele innych. Gdybyśmy zechcieli skorzystać z usług monitora transakcyjnego, zarządcy utrwalania, bezpieczeństwa - innymi słowy wszystkich tych usług dostępnych w kontenerze EJB musielibyśmy poznać pewien zestaw interfejsów i klas, i rozpocząć programowanie. Nie wspominam już nic o rozproszeniu aplikacji, gdzie chcielibyśmy rozlokować klasę na wielu serwerach i udostępnić je jako całość dla aplikacji klienckich. Nie ma co ukrywać - jest to wiele pracy. Z EJB3 sprawa sprowadza się do zadeklarowania klasy jako ziarno EJB odpowiednią adnotacją i temat dostępności wspomnianych usług mamy obsłużony.
 package pl.jaceklaskowski.ejb3;

import javax.ejb.Stateless;

interface Sklepikarz {
public void otworzSklep();
}

@Stateless
public class SklepikarzWykwalifikowany implements Sklepikarz {

public void otworzSklep() {
// wykonaj swoją pracę
}

}
Po udekorowaniu klasy adnotacją @Stateless staje się ona ziarnem EJB, a dokładniej SLSB. Znaczenie adnotacji rozpoznaje jedynie serwer aplikacyjny Java EE 5, więc wciąż jest to zwykła klasa, a dopiero środowisko serwera aplikacji nadaje jej specjalnego znaczenia jako ziarno EJB. Tym razem zwykła klasa jest już niezwykła, gdyż serwer aplikacji dla każdej metody publicznej przypisuje kontekst transakcyjny, bezpieczeństwo (wszystko mają domyślnie prawo wykonania metody), a pewne wyjątki wycofują transakcję automatycznie, podczas gdy inne niekoniecznie. Za wszystko odpowiada serwer aplikacyjny i stąd jego znaczenie w architekturach korporacyjnych korzystających z Korporacyjnej 5-tki (= Java EE 5). Wiele z trudności programistycznych serwer aplikacyjny zdejmuje z nas za pomocą m.in. specyfikacji EJB3. Dodając do tego inne specyfikacje budowania obiektowych aplikacji korporacyjnych mamy zestaw komponentów (= "klocki Lego"), za pomocą których możemy zbudować aplikację korporacyjną. Ot cała magia EJB3 i w ogóle Korporacyjnej 5-tki.

A gdzie znaleźć więcej informacji o EJB3? Zacząłbym od dostępnego za darmo streszczenia specyfikacji EJB3 - JSR 220: Enterprise JavaBeansTM,Version 3.0 EJB 3.0 Simplified API. Czyta się ją nadzwyczaj przyjemnie. Dodatkowo książka Billa Burke & Richarda Monsona-Haefela - Enterprise JavaBeans 3.0 z O'Reilly będzie wartościowym uzupełnieniem. Warto również rozważyć przejrzenie tematu EJB3 w Java EE Tutorial. Po tym zestawie już będzie wiadomo, czego potrzeba więcej. Aby urozmaicić lekturę, można popróbować się z EJB3 w akcji - polecam Eclipse + Geronimo lub NetBeans + GlassFish. Oba warte rozważenia dla początkujących. Część materiału przedstawiłem w swoich streszczeniach specyfikacji EJB3 w Notatniku w kategorii EJB3 oraz artykułach na moim Wiki. Miłego mielenia ziaren EJB3!

20 lipca 2008

Zmiany w NetBeans 6.5 nie tylko w harmonogramie, netbeans.keep.expansion oraz ukryte skarby JDK - jps i jstack

2 komentarzy
Przez długi okres czasu, od 10 lipca, wersja rozwojowa NetBeans IDE 6.5 była niedostępna, aż dopiero 3 dni temu - 17.07 - pojawiła się długooczekiwana nowiuteńka paczka dystrybucyjna netbeans-trunk-nightly-200807170007.zip (można zauważyć, że ponownie mamy przerwę w dziennych paczkach, bo jest 20.07, a wciąż w repozytorium najnowsza wersja to właśnie z 17.07!). Można, więc przysiąć i posprawdzać jego (nie)doskonałości, jednocześnie "zarabiając" kilka punktów w NetCAT 6.5. Tym razem obiecałem sobie, że przyjrzę się Groovy i Grails, których wsparcie jest nadzwyczaj wychwalane przez użytkowników groovy-grailsowych. Jeśli będzie można połączyć to z pracami wokół Korporacyjnej 5-tki z GlassFish v3 (w którym zagościło OSGi) to dlaczego nie poświęcić temu trochę czasu. Nie ma go wiele, więc jeśli go trwonić, to na rzeczy ciekawe, nieprawdaż?! W tym tonie udało mi się zapoznać z Mastering Grails: Build your first Grails application. Bardzo krótki acz treściwy artykuł prezentujący cechy Grailsów, które sprawiają, że programiści javowi nie muszą spoglądać w stronę Ruby on Rails (RoR). Na chwilę obecną wystarczy poznawania Grailsów, ale pytanie o możliwość integracji z innymi rozwiązaniami, np. opartymi o znaczniki JSP, pozostaje. Może ktoś rzucić trochę światła na kwestię integracji rozwiązań typu JSF z Grails? Czy to w ogóle jest porównywalne? Czy integracja ma rację bytu?

Po uruchomieniu NetBeansa pierwsze zaskoczenie - pojawiła się nowa grafika początkowa (ang. splash screen).

Ładniutki, nieprawdaż? Poza tą niefunkcjonalną zmianą, mamy domyślnie otwarty widok Tasks (Ctrl+6).

Zadania określane są przez znane i lubiane TODO, ale również kilka innych adnotacji (patrz Tools > Options > Miscellaneous > ToDo Tasks).

Przy okazji konfiguracji adnotacji dla zadań pojawiło się jedno z moich ulubionych słówek angielskich - miscellaneous. Jest ono o tyle ulubione, że wielu zapytanych nie wie, jak się poprawnie wymawia to słowo (pomijając, że wielu nie wie o jego istnieniu).

W kontekście domyślnego uruchomienia widoku Tasks, sądzę, że w końcu potraktuję swoje TODO w kodzie poważniej, bo przy każdorazowym uruchomieniu ich liczba z pewnością będzie przypominała o ich istnieniu. Zauważyłem pewną zależność między naszymi przyzwyczajeniami a domyślnymi ustawieniami narzędzi używanych na codzień. Wielu z nas zamiast dostosowywać narzędzie do siebie, dostosowuje siebie do niego. A tu proszę, NetBeans postanowił obdarzyć nas narzędziem, które dba o nasze zadania. Teraz może w końcu baczniej przyjrzę się zadaniom do wykonania (TODO) z jego pomocą. Jeszcze nie zastosowałem się do tych "zaleceń", ale już mi się podobają.

Ciekawostka z grupy NetCAT 6.5, której znajomość z pewnością daje poczucie zaawansowanego użycia NetBeans IDE podczas pracy. Jeśli potrzebujemy zachować stan rozwiniętych węzłów w drzewie (dowolnym, np. w oknie Projects będą to projekty i ich zasoby) to wystarczy...więcej w poniższej wiadomości:

On build 5.5 the Project Window remember the state of the node. while now 6.5 it will collapse to the root if we are going to restart the IDE.

This change was made intentionally (I thought earlier than 5.5, but perhaps not) - the reexpansion of the nodes was slowing down startup.

http://www.netbeans.org/issues/show_bug.cgi?id=55701

You should be able to enable the expansion by adding

-J-Dnetbeans.keep.expansion=true

to your netbeans.conf, but note that this mode is not tested.


Kolejną ciekawostką z programu NetCAT 6.5 jest narzędzie jstack, o którym nie miałem w ogóle świadomości istnienia (!) A narządko bardzo ciekawej funkcjonalności, bo prints Java stack traces of Java threads for a given Java process or core file or a remote debug server, czyli dokładnie to, czego w wielu momentach spowolnienia aplikacji javowej potrzebuję. Ni mniej, ni więcej - narzędzie umożliwia zerbanie danych do analizy prac JVM przez wypisanie sterty wywołań javy dla wybranego procesu, z pliku ze zrzutem pamięci (core) czy zdalnego serwera. Więcej o tym i podobnych narzędziach w NetBeans - How to Generate a Thread Dump. Okazuje się, że poza jstack jest również niejaki StackTrace. Teraz jakikolwiek problem wydajnościowy w Javie nie będzie mi straszny. Przy okazji, z dokumentacji jstack dowiedziałem się o kolejnym, nieznanym mi wcześniej, narzędziu jps, który wypisuje identyfikatory procesów javowych, np.:

C:\Documents and Settings\jlaskowski 2008-07-18 12:19:33,98
> C:\apps\java6\bin\jps.exe
32132 org.eclipse.equinox.launcher_1.0.100.v20080509-1800.jar
35188 NetworkServerControl
35684 Main
37884 Jps
30228 PELaunch
Teraz wystarczy podłączyć się do wybranego procesu javowego narzędziem jstack, aby rozeznać się w aktualnej sytuacji o stanie JVM (żeby tak prosto było zdiagnozować problemy w polskiej słuzbie zdrowia, o której tyle ostatnio. Gdybym wiedział numer procesu może mógłbym jakoś pomóc. ;-)):
 C:\Documents and Settings\jlaskowski 2008-07-18 12:21:39,67
> C:\apps\java6\bin\jstack.exe -l 35684
2008-07-18 12:23:57
Full thread dump Java HotSpot(TM) Client VM (10.0-b23 mixed mode):

"Inactive RequestProcessor thread [Was:Default RequestProcessor/org.netbeans.modules.xml.xam.AbstractModelFactory$1]" da
emon prio=2 tid=0x374a1400 nid=0x8100 in Object.wait() [0x3bb4f000..0x3bb4fc14]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:950)
- locked <0x09baa8a0> (a java.lang.Object)

Locked ownable synchronizers:
- None
...
"Finalizer" daemon prio=8 tid=0x31377400 nid=0x8a24 in Object.wait() [0x3184f000..0x3184fa94]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:116)
- locked <0x0549b4e0> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:132)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)

Locked ownable synchronizers:
- None

"Reference Handler" daemon prio=10 tid=0x31376400 nid=0x88b8 in Object.wait() [0x3164f000..0x3164fb14]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x0549aef0> (a java.lang.ref.Reference$Lock)

Locked ownable synchronizers:
- None

"VM Thread" prio=10 tid=0x31373000 nid=0x7654 runnable

"VM Periodic Task Thread" prio=10 tid=0x3139b400 nid=0x8504 waiting on condition

JNI global references: 2935
Warto zapoznać się z pełną dokumentacją narzędzi dostarczanych w ramach wybranej JVM, np. dla Sun JDK będzie to JDK Tools and Utilities. Nie wszystkie jednak narzędzia dostępne są na wszystkich platformach systemowych, gdyż narzędzia są dostarczane przez dostawcę JVM dla danej platformy, więc dla IBM JDK będzie to inny zestaw narzędzi, często wykraczający poza możliwości Sun JDK.

I wiadomość z ostatniej chwili w temacie zmian w harmonogramie NetCAT 6.5. Przesunęła się data wydania finalnej wersji NetBeans 6.5. Pojawił się niewielki the two weeks slip in the schedule, o którym pisze Jirka Kovalsky (głównodowodzący programu NetCAT 6.5):

Due to postponed Feature Freeze of PHP and GlassFish v3 support and high number of bugs we are forced to update some important milestones. Accordingly I had to adjust some NetCAT 6.5 dates and the new schedule is already published on the NetCAT 6.5 homepage (http://qa.netbeans.org/processes/cat/65)

Nowa wersja NetBeans IDE 6.5 dopiero 15 października. Jest szansa na wyłapanie większości błędów w nim i nauczeniu się kilku nowych szkieletów programistycznych, których wsparcie dostarcza, np. Grails. Gdybym tak mógł poczytać o integracji Grails z usługami dostarczanymi przez serwer Korporacyjnej 5-tki byłoby wspaniale. W połączeniu z OSGi byłbym w ogóle uszczęśliwiony.

18 lipca 2008

NetBeans 6 i jego edytor PageFlow do faces-config.xml

3 komentarzy
Pamiętam, że już jakiś czas tematu zastanawiałem się nad zastosowaniem edytora PageFlow do edycji faces-config.xml - główny plik konfiguracyjny aplikacji JavaServer Faces (JSF). Dzisiaj natrafiłem na wpis, który sprowokował mnie do zbadania tego tematu dokładniej. I warto było, bo kolejny temat mam z głowy. W końcu! Czy nie masz takich natarczywych tematów, które trapią Cię od wielu dni/tygodni/miesięcy, ale mimo to nie znalazłeś/-aś czasu, aby go rozwiązać?! Ja mam ich kilka i jeden właśnie zszedł z listy.

Głównym zadaniem edytora PageFlow, który służy do edycji pliku faces-config.xml, jest umożliwienie wprowadzania zmian w regułach nawigacyjnych aplikacji JSF w sposób graficzny bez konieczności grzebania się w zawiłościach pliku XML (cf. Page Flow Editor Functional Specification). Udostępnienie tej funkcjonalności po prostu zdejmuje z użytkownika obowiązek znajomości jego składni. I w zasadzie to jest jego główna i jedyna potrzeba korzystania. Skoro mniej musimy znać, aby poprawnie skonfigurować przepływ między stronami w aplikacji JSF, to właśnie to jest jego zaletą i tego oczekiwałbym od IDE.

Garść informacji o edytorze PageFlow dla faces-config.xml znajduje się w dokumencie PageFlow Editor for NetBeans 6.0 i jakkolwiek dotyczy wersji NetBeans 6.0, to niewiele zmieniło się od tego czasu. Dodatkowych informacji, a w zasadzie zrzutu ekranu, który uzmysławia możliwości PageFlow, można znaleźć we wpisie Net Beans (6.1) Page Flows, ale ponownie zbyt pobieżnie i niewiele. Dopiero podczas lektury tego wpisu zorientowałem się, czego mógłbym faktycznie oczekiwać od PageFlow. Do tej pory moje aplikacje JSF budowane w NetBeans składały się ze zwykłych stron JSP, które zawierały kontrolki JSF. Mówiąc językiem używanych szkieletów webowych, to był to jedynie JavaServer Faces.

Przy takiej konfiguracji PageFlow udostępniał jedynie 3 akcje dla stron JSP.

Zastanawiałem się wciąż po co ten plus po prawej stronie (u góry zakryty przez menu Delete). Kilkakrotnie napotykałem dyskusję dotyczącą Visual Web JavaServer Faces (w skrócie Visual Web) w kontekście budowania aplikacji JSF w NetBeans. Visual Web to zestaw kontrolek JSF, podobnie jak IceFaces, RichFaces, Tomahawk czy Tobago (pewnie jest ich znacznie więcej, ale te mi teraz przychodzą do głowy). Coś mi mówiło, że właśnie tutaj powinienem szukać odpowiedzi. Kiedy dodałem Visual Web JavaServer Faces do kategorii Frameworks we właściwościach projektu projektu JSF strony JSP stworzone jako Visual Web JSF Page były specjalnie traktowane przez NetBeans.

Nadal były stronami JSP, ale poza zmianą wizualną w widoku Projects, która polegała na zmianie ikony związanej ze stronami, do ich edycji mogłem użyć edytora Design, JSP i Java w jednym (czego nie miałem do dyspozycji przy "zwykłych" stronach JSF).

Zmiana również wpłynęła na dostępne menu w PageFlow związane ze stronami typu Visual Web.

Pojawiły się 3 nowe akcje i możliwe stało się wiązanie (tworzenie przepływu/nawigacji) między elementami strony - przycisk (ang. button) jako Add Button, odnośnik (ang. hyperlink) jako Add Hyperlink oraz odnośnik z obrazkiem (ang. image hyperlink) jako Add Image Hyperlink a innymi stronami w aplikacji. Mam wciąż pewne opory przed stosowaniem tego zestawu Visual Web, bo brakuje mi sprawdzenia na ile jest to przenośne między serwerami aplikacyjnymi (np. czy będę mógł uruchomić aplikację zbudowaną z pomocą Visual Web na Apache Geronimo czy WASie) oraz potencjalne problemy podczas integracji z innymi, wspomnianymi wcześniej, zestawami kontrolek JSF. Temat zostawiam do zbadania na później, chyba że ktoś już zna odpowiedź i zechciałby podzielić się wrażeniami.

Ostatecznie PageFlow prezentuje się następująco.

Od razu można zgadnąć, które strony są typu Visual Web, a które "zwykłymi" JSP. I to jest właśnie zagadka na weekend - rozpoznać typy stron na załączonym wyżej zrzucie ekranu. Miłej zabawy!

15 lipca 2008

Słów kilka o Maven 2 w NetBeans 6.5, Sun Certified NetBeans IDE Specialist oraz "GWT w praktyce" Power Netu

4 komentarzy
Piotr Pietrzak w komentarzu do Klasyfikatory w Maven 2 oraz polonizacja NetBeans IDE odpowiedział na wczorajsze moje bolączki związane z brakiem funkcjonalności NetBeans IDE odpowiadającej eclipsowej wtyczce do obsługi projektów mavenowych - m2eclipse w postaci...filmu (!) Wspaniała forma dyskusji w Sieci. Wierzę, że będą kolejne. Tylko, dlaczego nie ma głosu?! ;-)

Temat pobrania źródeł do zależności projektu mavenowego w NetBeans sprowadza się do Add local sources pod prawym przyciskiem myszki dla wybranej zależności

bądź po prostu Download All Library Sources na węźle Libraries w projekcie.

Co ciekawe, po pobraniu wszystkich źródeł, nazwy plików udekorowane są ikonką ze słoikiem i pakunkiem.

Natrafiłem przy okazji na inną ciekawostkę związaną ze wsparciem projektów mavenowych przez NetBeans 6.5 we współpracy z wtyczką Mevenide-NetBeans - wsparcie dla edycji pom.xml. Co ja będę się rozpisywał, sam zobacz (tym razem w postaci zrzutów ekranu, ale może kolejnym razem będzie bardziej filmowo?!). W lokalnym repozytorium mam

a w edytorze jako podpowiedź otrzymuję (Ctrl+Spacja)

Miła niespodzianka, chociaż zanim mnie mile zaskoczyło nie mogłem doczekać się zaindeksowania repozytoriów mavenowych. Dobrze, że cała operacja odbyła się w tle.

Podczas moich dzisiejszych wyczynów programistycznych z NetBeans IDE 6.5M1 potrzebowałem otworzyć klasę w projekcie i jako, że nie jest to Eclipse Ctrl+Shift+T nie działa...domyślnie. W takich przypadkach wspieram się zawsze pomocą Google, ale tym razem miałem wszystko pod ręką, lokalnie. Help > Keyboard Shortcuts Card

po którym otwiera się dokument pdf ze skrótami. Wystarczyło Ctrl+F (szukaj), wpisanie ciągu type, <Enter> i mam - Ctrl-O/Alt-Shift-O Go to type/file. Nie mogłem oprzeć się, aby nie sprawdzić, czy funkcjonalność znana mi z Eclipse dostępna jest i w NetBeans - wyszukiwanie typów po ich skrótach, np. NullPointerException to NPE, albo NoClassDefFoundError to NCDFE. To również jest w NetBeans! Miło.

Tylko jedno mi doskwiera teraz - dlaczego eclipsowe Ctrl+O w edytorze Java to Ctrl+Shift+F12 w NetBeans?! Nic nie przychodzi mi do głowy, aby podmienić to jakoś sensownie, ale sądzę, że to jedno z bardziej użytecznych funkcji IDE - wyświetlenie elementów typu i możliwość przejścia do wybranego, więc należy się coś bardziej ludzkiego. Może jednak warto zmienić mapowanie klawiszy na eclipsowe? Mam takie skrzywienie uniksowe, gdzie edytuję pliki w vi, podczas gdy na linii komend korzystam z trybu Emacs. Pewnie podobnie będzie z klawiaturą w NetBeans. Jak się człowiek do czegoś przyzwyczai, to trudno mu się oderwać od tego.

Na grupie NetCAT 6.5 Jirka (głównodowodzący programem) poprosił o ocenę przygotowywanego certyfikatu Sun Certified NetBeans IDE Specialist. Czy uważacie, że istnieje faktycznie potrzeba na Sun Certified Netbeans IDE Specialist? Co ono miałoby certyfikować?! Znajomość skrótów klawiszowych? Pozycji menu? A co w przypadku pracy z tłumaczonym środowiskiem? Możesz wyrazić swój głos w ankiecie Sun Certified NetBeans IDE Specialist. Miło zostałem zaskoczony zakresem egzaminu i uważam, że będzie doskonałym sprawdzianem poprawnego użycia NetBeans IDE jako środowiska pracy. Ciekawe, kiedy można oczekiwać odpowiedzi zespołu Eclipse. Fajne takie SCeNBIS oraz ECIS ;-)

Na koniec wiadomość z ostatniej chwili - pojawiła się ciekawa oferta na półce wydawnictwa Power Net - GWT w praktyce autorstwa Roberta Coopera oraz Charles'a Collinsa. Książka została przetłumaczona przez Marcina Leszczyńskiego, który znalazł swoje miejsce w podziękowaniach w wersji angielskiej (!) I ja przyłączam się do podziękowań za podjęcie trudu przetłumaczenia książki na polski. Wbrew panującemu obyczajowi na polskim rynku wydawniczym literatury informatycznej, tłumaczenie pojawiło się 2 miesiące po premierze angielskojęzycznej. Najwyraźniej można, jak się chce. Niedawno miałem okazję ponownie powalczyć z GWT i przymierzałem się do oryginalnej wersji książki, ale skoro jest dostępne polskie tłumaczenie, dlaczego nie zacząć lektury właśnie od niej? Jako rozgrzewkę można zabrać się za lekturę przykładowego rozdziału, który jest dostępny na stronie książki. Najwyraźniej Power Net zaczyna stanowić ciekawą alternatywę dla innych wydawnictw informatycznych z coraz to znaczącymi tłumaczeniami. Gratulacje!

14 lipca 2008

Klasyfikatory w Maven 2 oraz polonizacja NetBeans IDE

2 komentarzy
Już jakiś czas minął od zgłoszenia usprawnienia związanego z niedostępnością dokumentacji javadoc w dystrybucji Apache Wicket (WICKET-1587 Include javadoc in the distro). Okazało się, że właśnie dzisiaj zamknięto moje zgłoszenie jako Duplicate ze wskazaniem na kolejne zgłoszenie WICKET-543 need javadocs embedded in the Wicket 1.3 zip file. W WICKET-543 zgłoszenie kończy się wskazaniem na plik dokumentacji w publicznym repozytorium mavenowym Wicketa - http://repo1.maven.org/maven2/org/apache/wicket/wicket. Wystarczy, więc pobrać dokumentację javadoc (lub jeszcze lepiej kodów źródłowych, które są tam również umieszczone) i sprawa wydaje się zamknięta.

W/g mnie nie rozwiązuje to głównego problemu niedostępności dokumentacji w samej paczce dystrybucyjnej Wicketa, bo nie wszyscy przecież korzystają z Mavena do zarządzania projektami, a nawet pracując z nim można nie zorientować się, gdzie jest dostępna dokumentacja do pobrania. Może jest to jednak efekt "nowych" czasów, gdzie jeśli nie korzystasz z Mavena toś...i tu należałoby umieścić coś niestosownego, bo przecież każdy wie jak z niego korzystać, albo jak pobrać plik z jego repozytorium. Nieprawdaż?! Ja jednak należę do tych (nie)szczęśników, którzy zazwyczaj pracują z Mavenem, jeśli idzie o zestawianie projektów poza IDE, więc mogę przychylić się do tego rozwiązania jako satysfakcjonujące. W Eclipse dostępna jest wtyczka m2eclipse, która umożliwia pobranie źródeł dla zadanych zależności (Maven > Download Sources), ale już w NetBeans mimo, dostępności wtyczki Mavenide-NetBeans, nie znalazłem podobnej funkcjonalności. Pozostaje rozpoznać temat z poziomu linii poleceń i zdefiniować odpowiednie polecenie dla NetBeans, bądź innego IDE w użyciu, jeśli dedykowane menu nie istnieje.

Rozróżnienie artefaktów pochodzących z pojedyńczego projektu (modułu) odbywa się z użyciem klasyfikatora (ang. classifier), które jest kolejnym elementem rozróżniania artefaktów w Maven 2 zgodnie z zasadą nazewniczą przedstawioną w rozdziale POM Relationships. Najbardziej powszechnym użyciem klasyfikatora to wskazanie pliku z dokumentacją javadoc (klasyfikator: javadoc) oraz źródłami (klasyfikator: sources). Deklaracja zależności w projekcie mavenowym odbywa się w pliku pom.xml, np.:
 <dependencies>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>1.4-m3</version>
</dependency>
</dependencies>
i dotyczy zazwyczaj artefaktów, które są plikami jar (domyślna wartość dla elementu dependency/type to jar) z pustym klasyfikatorem. Wskazanie na zasób (artefakt) o klasyfikatorze javadoc wymaga skorzystania z elementu classifier z wartością javadoc. Pytanie, które należy w tym momencie zadać, to przypadek użycia, w którym chcielibyśmy skorzystać z możliwości zadeklarowania zależności projektu od klasyfikatora javadoc czy sources (pozostałe klasyfikatory pozostawiam do własnego przemyślenia). Dla przypadku wyłącznego pobrania javadoc czy źródeł z centralnego repozytorium Mavena korzysta się z pomocy dodatkowego parametru konfiguracyjnego wtyczki, która umożliwia skorzystanie z danego typu klasyfikatora (udostępnia rozwiązanie przypadku użycia, w którym dany klasyfikator gra znaczącą rolę).

Weźmy jako przykład pracę z javadoc. Jeśli chciałbym skorzystać z javadoc do umieszczenia jej w dystrybucji mojego projektu skorzystam z wtyczki maven-assembly-plugin, która potrafi "złożyć" plik wynikowy paczki dystrybucyjnej projektu, potencjalnie z dołączeniem dokumentacji javadoc dla wybranej zależności. W przypadku korzystania z dokumentacji javadoc czy źródeł w środowisku Eclipse wtyczka maven-eclipse-plugin generująca definicję projektu eclipsowego na podstawie pom.xml pozwala na określenie wymagania podpięcia javadoc czy źródeł do projektu - parametry -DdownloadJavadocs=true i -DdownloadSources=true, odpowiednio (patrz Attach Library Sources and Javadocs).

Wniosek jest jeden: w zależności od wymagań zazwyczaj nie przyjdzie Tobie skorzystanie z artefaktu o zadanym klasyfikatorze bezpośrednio, a raczej pośrednio, poprzez zależność w pom.xml czy konfigurację wtyczki. Jeśli jednak potrzebujemy pobrać pojedyńczy plik z repozytorium mavenowego, np. z dokumentacją javadoc, wystarczy skorzystać z wget czy podobnego narzędzia. To jednak sprowadza temat do bardzo znanej i lubianej kwestii doboru właściwego narzędzia do danego zadania. Kwesię obsługi javadoc w projekcie mavenowym zdaje się, że mam(y) rozwiązaną.

Kiedy teraz przyjdzie mi pracować z projektem mavenowym w środowisku Eclipse bez pomocy wtyczki m2eclipse wystarczy uruchomić polecenie
 mvn eclipse:eclipse -DdownloadSources=true  -DdownloadJavadocs=true
i zaimportować projekt, aby móc cieszyć się z pomocy kontekstowej javadoc oraz możliwości przejścia do kodów źródłowych dla klas zależności projektowej. Warto było zgłosić usprawnienie do Wicketa, aby w końcu rozpoznać to wszystko. Teraz już wszystko powinno być jasne.

Od kilku dobrych miesięcy trwają prace nad polonizacją NetBeans IDE 6. Prace trwają i mimo nadchodzącej wersji NetBeans IDE 6.5 (od 14-tego rozpoczynają się prace w NetCAT 6.5), wciąż nie ma produkcyjnej wersji NetBeans w języku polskim. Jeśli jesteś zainteresowany/-a posiadaniem spolszczonego NetBeansa i chciał(a)byś mieć swój udział w projekcie tłumaczenia przyłącz się do zespołu polonizującego NetBeans. Proponuję zacząć już dzisiaj.

11 lipca 2008

Zaproszenie do NetCAT 6.5 oraz NetBeans Dream Team jednego dnia

3 komentarzy
Dzisiaj spędziłem czas w cieniu rozpracowania zawiłości IBM WebSphere Application Server 6.1 i przyznaję, że wymagający klient, dociekający każdej funkcjonalności serwera aplikacyjnego, to skarb, który należy pielęgnować i dbać o niego z całych sił. Jakby przeciwieństwo powszechnego przekonania, że klient to wróg numer jeden, a właśnie to, co powoduje, że owych "szkodników" (aka klientów) tak nie lubimy, jest właśnie tym, co sprawia, że zgłębiamy temat intensywniej i stajemy się technicznie bardziej zaawansowanymi. Mam przyjemność pracować z dwoma warszawskimi klientami, którzy faktycznie wykorzystują każdy element WASa i IBM WebSphere Process Server 6.0.2 w ich najdrobniejszych szczegółach i jeszcze nie było dnia, abym nie dowiedział się czegoś nowego. Zabawy co nie miara!

Tym bardziej ucieszyłem się, kiedy zaglądając do mojej skrzynki pocztowej miałem możliwość przeczytania dwóch zaproszeń z całkiem innej półki - NetBeans.

Pierwsze z nich to zaproszenie do programu NetCAT 6.5:

Welcome to the NetCAT 6.5 program!

Dear NetCAT 6.5 applicant,

Congratulations! You have been selected to participate in the NetBeans 6.5 Community Acceptance Testing program. The response to the program announcement was very high again and the selection process was difficult at best, but your experience and testing offer met our selection criteria.

On _July 14th_ you will be automatically subscribed to netcat@netbeans.org alias and receive further information regarding your testing activites. This mailing list will be the main communication channel for NetCAT 6.5 program and in this regard we would like to ask you to read and adhere to our NetCAT Etiquette [1].

[1] http://qa.netbeans.org/processes/cat/65/etiquette.html

Your feedback is important to us and we hope that you will be an active member of the NetCAT 6.5 team. Thanks again for your interest in improving NetBeans and welcome aboard!

Best regards,
--
Jiri Kovalsky
NetCAT 6.5 Program Coordinator
http://qa.netbeans.org/processes/cat/65/index.html


Drugie zaproszenie to jeszcze większa niespodzianka - zaproszenie do grupy NetBeans Dream Team.

You are formally invited to join the NetBeans Dream Team

Hello and congratulations,

You are invited to join the NetBeans Dream Team. Please read more about us at:
http://wiki.netbeans.org/NetBeansDreamTeam

You were selected using the process located at:
http://wiki.netbeans.org/NBDTNewMemberRules

You are obviously not required to become a member, but we have recognized your contributions within the NetBeans community, and would like to formally invite you to join our group.

You may read more about our mission at:
http://wiki.netbeans.org/DTMissionStatementAndProcess

and some things we would like to work on at:
http://wiki.netbeans.org/NetbeansDreamTeamIdeasAndProjects

We sincerely hope you accept this invitation and we look forward to working with you to make our NetBeans community better.

Below we have provided some preliminary introductory questions for you to provide answers to the current members. This will help us get to know you better. Please respond with the answers, and if you accept this invitation we will get you setup within our infrastructure. If you choose not to accept at this time, we do hope you'll consider us in the future, and thank you for your contributions:

1) Do you accept this invitation? (if not, then please do not feel obligated to answer the other questions, and thank you for your attention)

2) What is your name?

3) What is your netbeans user ID? This helps us see your issues in IZ and other community contributions.

4) Where do you live?

5) What are some interesting things about you: hobbies, family, etc?

6) What are your favorite NB features?

7) What are some interesting features you would like to add to the IDE?

8) Are you a NetBeans RCP/Platform developer/user?

9) What are some interesting features you would like to add to the RCP/Platform (if a user)?

10) What do you like most about the NetBeans community?

11) What are some things you would most like to change in the NetBeans community?

12) What are some other open-source communities you are involved?

13) What are your blog and home page addresses?

14) What email address should the Dream Team use to contact you? (this email address will also be used to sign you up to the Dream Team mailing list, Yahoo Tech Group, etc)

Thank you for your attention,

Wade Chandler

==================
Wade Chandler, CCE
Software Engineer and Developer, Certified Forensic Computer Examiner, NetBeans Dream Team Member, and NetBeans Board Member
http://www.certified-computer-examiner.com
http://wiki.netbeans.org/wiki/view/NetBeansDreamTeam
http://www.netbeans.org


Nic dodać, nic ująć. Dzisiejszy dzień przebiegł niezwykle interesująco. Z wyróżnieniami przychodzą obowiązki, jak stwierdził kolega Marcin, a z nowymi obowiązkami nowe doświadczenia, więc zabawa wciąż trwa. Może w końcu uda mi się zabrać ponownie za tą wtyczkę NetBeans dla Apache Geronimo?! Są chętni mi pomóc? Z wielkim entuzjazmem przyjąłbym nawet najmniejszą pomoc.

10 lipca 2008

Mapowanie encji w JPA - Strategia złączeniowa

1 komentarzy
Dobrym miernikiem nabytej wiedzy o Korporacyjnej Javie 5 (Java EE 5) może być podejście do egzaminów SCBCD, SCWCD czy SCEA , ale również aktywne uczestnictwo w grupach dyskusyjnych poruszających tą tematykę. Jedną z takich grup jest grupa dyskusyjna użytkowników serwera aplikacyjnego Java EE 5 - Apache Geronimo - user@geronimo.apache.org. Ostatnie pytanie error writing tuple to database "the owning entity is not mapped" geronimo 2.1.1 zdopingowało mnie do dokładniejszego przyjrzenia się tematowi odwzorowywania hierarchii dziedziczenia obiektowego klas encji na struktury relacyjne w bazie danych. W zasadzie teoretycznie temat został przedstawiony w mojej relacji z lektury specyfikacji Java Persistence API (JPA) - Java Persistence - Rozdział 2 Entities zakończony, ale pewnie z braku przykładów czułem pewien niedosyt.

Tak rozpoczyna się kolejny artykuł mojego autorstwa Mapowanie encji w JPA - Strategia złączeniowa, do lektury którego zapraszam. Uwagi/komentarze i pomysły dalszych materiałów mile widziane. Miłej lektury!

09 lipca 2008

NetBeans IDE 6.5M1 dostępny i algorytmiczna oferta pracy z Mój Startup

51 komentarzy
Niektórzy mają wakacje, jeszcze niektórym zechciało się pisać wpisy na blogu, a jeszcze niektórzy robią coś pożytecznego i wytrwale programują. W zespole NetBeans praca zdaje się, że wre na całego, czego dowodem jest kolejna wersja NetBeans IDE. Jeszcze nie ostygła wersja 6.1, a już mamy NetBeans IDE 6.5 Milestone 1 (NetBeans IDE 6.5M1). Wspominałem o programie NetBeans Community Acceptance Test (NetCAT) dotyczącym wersji 6.5 w Umiędzynarodowienie w JBoss Seam, NetCAT 6.5 oraz nowa grupa oferty-pracy-java, w którym można wyrazić swoją opinię o tym wydaniu i...jeszcze zgarnąć nagrodę (poza sławą i chwałą). Nie pozostaje nic innego, jak tylko przyłączyć się do zespołu NetCAT 6.5 i wyrazić, co człowiekowi leży na sercu, w kontekście tego wydania (inne sprawy sercowe nie są obsługiwane ;-)) Pewnie nie dla wszystkich jest to The only IDE you need! (za reklamą NetBeans IDE 6.5). W ogłoszeniu napisano:

This stabilized development build contains the following new & noteworthy features:
  • PHP
    • Enhanced Code Completion
    • Database-related code snippets
    • Multiple project configurations
    • Find Usages
  • Ajax
    • JavaScript Debugger
    • JavaScript Library Manager
    • Bundled JavaScript Libraries
  • Groovy
    • Editor
    • Java SE Project Integration
    • Grails support
  • Java
    • Javadoc Anlyzer
    • Call Hierarchy
    • CamelCase code completion
  • Debugger
    • New Multithreaded Debugging Support
    • Debugging Window
    • Current Thread Chooser
  • Additional enhancements have been made to
    • Web Frameworks (Spring, Hibernate, JSF, JSF CRUD Generator, JPA)
    • Ruby
    • Database
    • Mobility
    • GUI Builder
    • Web Services
    • Improvements to XML and Schema Tools
Note: The UML feature is not available in Milestone 1, but is planned for Beta. The development team is migrating UML to the NetBeans Visual Library, to make UML completely open source. Please see UML Current Projects for additional information.

Get more details about these features and additional New and Noteworthy Features http://wiki.netbeans.org/NewAndNoteWorthy available in the release. The final NetBeans IDE 6.5 release is planned for Fall 2008. We welcome and encourage feedback about your experience using the NetBeans IDE.

Bardzo imponująca lista funkcjonalności, nieprawdaż?

Jestem stałym czytelnikiem bloga Mój Startup, w którym pojawiła się niezwykle ciekawie przedstawiona oferta pracy dla programisty java zawierająca zadanko na znajomość algorytmiki. Ciekawym Waszych rozwiązań.

Napisz funkcję (w dowolnym języku programowania), która mają tablicę o długości N zawierającą liczby z zakresu 1 do N stwierdzi, czy występują w niej duplikaty (czy da się to rozwiązać w czasie liniowym? przy stałej pamięci? bez niszczenia zawartości tablicy?)

Czas liniowy jak najbardziej (współczynniki kosztów poszczególnych algorytmów będą różne), stała pamięć jak najbardziej zakładając, że N jest dowolne acz ustalone przed uruchomieniem (tutaj może pojawić się klucz do zmniejszenia kosztu) i ostatecznie nie niszczymy zawartości tablicy, gdyż tworzymy jej kopię gwarantując, że jej rozmiar nie będzie zależny od rozmiaru danych wejściowych (gwarancja algorytmu w miejscu). Czas napisania takiego algorytmu sądzę, że udałoby się zamknąć w 15 minutach. Są chętni do podjęcia pracy? Nawet, jeśli niekoniecznie samej pracy, to może samego zadania? Bardzo spodobała mi się tak przedstawiona oferta pracy. Gratuluję pomysłu. Sądzę, że może być ich więcej na dopiero co założonej grupie oferty-pracy-java, gdzie tego typu oferty powinny być normą. Czyżby nowa jakość na polskim rynku ofert pracy?!

02 lipca 2008

Umiędzynarodowienie w JBoss Seam, NetCAT 6.5 oraz nowa grupa oferty-pracy-java

6 komentarzy
W końcu natrafiłem na notkę odnośnie roli seam.properties w aplikacji w książce Beginning JBoss® Seam: From Novice to Professional wydawnictwa Apress oraz gdzieś w Sieci. Cała magia seam.properties to przede wszystkim oznaczenie archiwum WAR lub JAR jako zawierające komponenty seamowe i stąd konieczność umieszczenia go w /WEB-INF/classes w aplikacji webowej, aby Seam zechciał rozważyć przeszukiwanie aplikacji w celu "namierzenia" klas oznaczonych adnotacją @Name. Plik seam.properties może być całkowicie pusty - wystarczy jego istnienie. Trudno jednak zrozumieć, dlaczego umieszczenie definicji komponentów w components.xml działa, a już przeszukiwanie ich w archiwum nie. Czyż Seam nie dowiedział się właśnie poprzez plik components.xml, że ma do czynienia z aplikacją seamową?! Na chwilę obecną nie zamierzam zaglądać do kodu źródłowego, ale pewnie tam należałoby szukać odpowiedzi. Chętni?! ;-)

Dzisiaj na tapetę poszedł temat umiędzynarodowienia aplikacji seamowej (przypomina mi się temat Umiędzynarodowienie w Apache Wicket i trochę ckni mi się do Wicketa i możliwości jego uruchomienia na OSGi). Temat umiędzynarodowienia aplikacji korzystającej z JavaServer Faces był już przeze mnie przedstawiany w artykułach requiredMessage i resource-bundle - udoskonalona kontrola komunikatów w JSF 1.2, Uruchamiamy pierwszą aplikację w technologii JavaServer Faces, Tworzenie aplikacji z JavaServer Faces, Apache Maven i Apache Geronimo czy JavaServer Faces i Spring Framework w parze z Apache Maven i Apache Geronimo. Wszystkie dotykają tematu użycia message-bundle w faces-config.xml, kontrolki <f:loadBundle> na stronie JSF, gdzie korzysta się z tłumaczeń oraz wskazanie na niego z danego pliku tłumaczeń - #{komunikaty['wprowadz_imie']}. Jest tego trochę do zapamiętania, co Seam zauważalnie skrócił.

Pierwsza różnica między "czystą" (nieseamową) aplikacją JSF a opartą o Seama to założenie, że wszystkie pliki properties z tłumaczeniami składają się na jedną mapę messages klucz-tłumaczenie. W przypadku JSF mamy mapę per plik tłumaczeń. Kolejna zmiana to zniesienie obowiązku definiowania plików tłumaczeń w faces-config.xml - obowiązkowym pliku konfiguracyjnym każdej aplikacji opartej o JSF. I na koniec podsumowania różnic, Seam znosi obowiązek deklarowania użycia pliku tłumaczeń za pomocą <f:loadBundle>. Z Seamem wystarczy utworzyć pojedyńczy plik messages.properties dla wybranych języków i użyć konstrukcji #{messages['klucz']} w dowolnym miejscu strony JSF. Oczywiście istnieje możliwość zdefiniowania wielu plików tłumaczeń. "Gdzie?" - zapytasz. Oczywiście w opcjonalnym components.xml, który wraz z kilkoma innymi opcjonalnymi plikami xmlowymi przejął rolę obowiązkowego faces-config.xml w JSF (podkreślam użycie słów opcjonalny i obowiązkowy).

Więcej informacji ze źródła o umiędzynarodowieniu aplikacji seamowych w dokumentacji Seama - Chapter 15. Internationalization, localization and themes, a w szczególności 15.3.1. Defining labels. Podczas poznawania mechanizmu tłumaczeń w Seamie brakowało mi wiedzy, którą ostatecznie udało mi się znaleść na forum Seam Users w wątku Including a resource bundle not called messages*.

Umiędzynarodowienie mojej aplikacji seamowej, którą rozwijam od kilku dni, rozpocząłem od zmian w pliku components.xml, gdzie wskażę pliki tłumaczeń.
 <?xml version="1.0" encoding="UTF-8"?>
<components
xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.0.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">
<core:init debug="true" />
<core:resource-loader>
<core:bundle-names>
<value>komunikaty</value>
<value>messages</value>
</core:bundle-names>
</core:resource-loader>
</components>
Przypomnę, że jest to krok opcjonalny i domyślnie Seam poszukuje pliku messages.properties dla danego języka, np. messages_pl.properties dla polskiego. Plik musi znajdować się w ścieżce klas aplikacji, co w moim przypadku aplikacji webowej sprowadziło się do umieszczenia go w katalogu /WEB-INF/classes. W powyższej konfiguracji w components.xml dodałem również użycie pliku komunikaty_pl.properties.

Opcjonalnie zdefiniowałem domyślny język aplikacji (polski) i inne wspierane języki (polski) w faces-config.xml:
 <?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<application>
<locale-config>
<default-locale>pl</default-locale>
<supported-locale>pl</supported-locale>
</locale-config>
<view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>
W ten sposób zagwarantowałem, że jedynym słusznym językiem w aplikacji będzie polski. Wyboru nie ma.

Zawartość pliku messages_pl.properties:
 kategoria.tytul=Administracja kategoriami
oraz komunikaty_pl.properties:
 kategoria.nazwa=Nazwa
kategoria.opis=Opis
Oba pliki muszą znaleźć się na ścieżce klas, np. /WEB-INF/classes w ramach archiwum war.

Mając tak zdefiniowane pliki tłumaczeń zmodyfikowałem stronę kategoria.xhtml:
 <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<head>
<title>#{messages['kategoria.tytul']}</title>
</head>
<body>
<f:view>
<h:form>
<s:validateAll>
<h:panelGrid columns="2">
#{messages['kategoria.nazwa']}: <h:inputText value="#{kategoria.nazwa}" required="true" />
#{messages['kategoria.opis']}: <h:inputText value="#{kategoria.opis}" required="true" />
</h:panelGrid>
</s:validateAll>
<h:messages />
<h:commandButton value="Dodaj" action="#{kategoriaAgent.dodaj}" />
<br />
<h:outputText value="Brak kategorii" rendered="#{kategorie.rowCount==0}" />
<h:dataTable var="ktgria" value="#{kategorie}" rendered="#{kategorie.rowCount>0}">
<h:column>
<f:facet name="header">
<h:outputText value="Nazwa" />
</f:facet>
<h:commandLink value="#{ktgria.nazwa}" action="#{kategoriaAgent.wybierz}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Opis" />
</f:facet>
<h:outputText value="#{ktgria.opis}" />
</h:column>
<h:column>
<h:commandButton value="Delete" action="#{kategoriaAgent.skasuj}" />
</h:column>
</h:dataTable>
<h3><h:outputText value="#{kategoriaWybrana.nazwa}" /></h3>
<div><h:outputText value="#{kategoriaWybrana.opis}" /></div>
</h:form>
</f:view>
</body>
</html>
Na uwagę zasługuje użycie #{messages['kategoria.tytul']} w tytule poza sekcją <f:view> oraz #{messages['kategoria.nazwa']} i #{messages['kategoria.opis']} w <h:panelGrid>. Przypomnę, że wszystkie komunikaty trafiają do jednej zbiorczej mapy - messages, więc należy zagwarantować unikalność zawartych w niej kluczy tłumaczeń, np. poprzedzając nazwą strony, w której się znajdują.

Uruchomienie strony kategoria.xhtml, to jak można się domyśleć pojawienie się napisów z plików tłumaczeń. Proste, nieprawdaż?

Na zakończenie kilka słów spoza obszaru Seama. Właśnie pojawiło się zaproszenie do NetBeans IDE 6.5 Community Acceptance Testing program (NetCAT). W programie NetCAT miałem już przyjemność uczestniczyć w poprzednich edycjach i wiele mogłem się w nich nauczyć samego NetBeansa, ale również i technologiach Korporacyjnej Javy recenzując artykuły o nich i samemu sprawdzając ich działanie w NB. I tym razem nie mogłem sobie odpuścić zgłoszenia się do programu, szczególnie, że z tą wersją rokuję pewne nadzieje w kontekście znaczącego usprawnienia we wsparciu dwóch serwerów aplikacyjnych IBM WebSphere Application Server 6.1 oraz Apache Geronimo. Może się do czegoś przydam i sprawię, aby pracowało się przyjmniej z NetBeans 6.5? ;-) A Ty? Każdy może się przyłączyć, więc szkoda czasu na zbędne zastanawianie się - lepiej ten czas przeznaczyć na poznawanie błędów^H^H^Hfunkcjonalności NB 6.5.

Kilka dni temu Michał B. podjął się tematu wyjaśnienia odmiany słowa Java i jego pisowni w komentarzu do W sprawie Recenzja książki "Hibernate. Od Nowicjusza do Profesjonalisty". Odpowiedź od jego znajomego filologa trochę mnie zaskoczyła:

"wyraz 'Java' proponuję używać tylko w formie mianownikowej i odmieniać tylko wyraz 'język' - czyli np. języka Java, o/w języku Java.
To zapewni jednoznaczność terminologii w tekstach - oczywiście mówiąc nie trzymałbym się kurczowo takiej opcji - tu może być sama [dżawa] a formy [w dżawie] itp. wystarczą (o czym sam doskonale wiesz:)) "


Zaskoczeni podobnie jak ja? Jestem zdania, że można odmieniać słowo Java w dowolnym zestawieniu, czyli o javie, z javą i bez javy (chociaż to ostatnie nie przechodzi mi jakoś przez gardło ;-))

I na koniec informacja o dedykowanej grupie oferty-pracy-java, gdzie zamieszczane są wyłącznie oferty dotyczące obszaru programowania, testowania czy projektowania z użyciem technologii javowych z uwzględnieniem widełek płacowych. Jeśli uważasz, że jest coś więcej, co powinno pojawiać się w każdym ogłoszeniu o pracę, zapraszam do udziału w grupie i wprowadzenia stosownych zmian. Każdy ma prawo głosu, a celem jest stworzenie miejsca, w którym oferty będą tak profesjonalne, jak osoby, które z nich zamierzają skorzystać. My jako owa wykwalifikowana kadra możemy wpłynąć na kształt ofert i korzystania z nich dla dobra własnego. W ten sposób z pewnością uda nam się wypracować nowy styl pisania ofert z właściwymi wymaganiami, widełkami płacowymi, dodatkami, itp. Grupa jest moderowana i przy rejestracji należy określić swoją rolę - oferent/rekruter vs zainteresowany (wyłącznie dla celów...hmm...nie mam pojęcia jakich, ale pomyślałem, że dobrze wiedzieć jakie są proporcje). Dyskusje o uszczegółówienie ofert jak najbardziej wskazane. Grupa jest publiczna. Archiwum do przeglądania przez każdego, ale jedynie członkowie mogą dyskutować na grupie (po zatwierdzeniu posta przez moderatora). Sądzę, że warunki są idealne do wymagań obu stron - firm rekrutacyjnych i kadry pracowniczej. Promocja siebie jak najbardziej wskazana przez wysłanie CV na grupę. Wszystko, co sprawi, że będzie można znaleźć swoją wymarzoną pracę łatwiej mile widziane. Zapisz się i działaj!

Pytanie konkursowe: Jak nazywa się mapa tłumaczeń w Seamie? I takie bardzo zaawansowane: W jaki sposób (gdzie i jak) definiuje się wiele plików tłumaczeń w Seamie?