wtorek, 12 października 2010

PowerMock i przetestujesz wszystko...

Poprzednie dwa posty pokazywały jak można testować metody i pola prywatne klasy. Zapis nie za piękny, czytelność słaba, ogólnie takie rozwiązanie takie se. Na szczęście istnieje bardzo przyjemne narzędzie umożliwiające wyżej wymienione zagadnienia i wiele, wiele innych.

PowerMock to framework rozszerzający biblioteki takie jak: EasyMock i Mockito. Odsyłam do oficjalnej strony w celu zapoznania się na co konkretnie pozwala PowerMock. Ja używam go wraz z Mockito i nie miałem do tej pory żadnych problemów. Poniżej prosty przykład użycia.

Klasa do testów:
public class SomeClass {
    
    private Integer privateField;

    private boolean privateMethod(String s, int i){
        return false;
    }
}
Klasa testująca:
import static org.powermock.reflect.Whitebox.getField;
import static org.powermock.reflect.Whitebox.invokeMethod;

import java.lang.reflect.Field;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
public class SomeClassTest {
    
    @Test
    public void shouldTestPrivateMethod() throws Exception {

        //given
        SomeClass someClass = new SomeClass();

        //when        
        boolean test = invokeMethod(someClass,"privateMethod", "Test", 1);

        //then
    }
    
    
    @Test
    public void shouldTestPrivateField() throws IllegalArgumentException, IllegalAccessException {

        //given
        SomeClass someClass = new SomeClass();

        //when
        Field field = getField(SomeClass.class, "privateField");
        Integer testInteger = (Integer) field.get(someClass);

        //then
    }
}

WhiteBox oferuje jak wspomniałem o wiele więcej i warto się z tą funkcjonalnością zaznajomić.

czwartek, 30 września 2010

Mechanizm refleksji - dostęp do prywatnych atrybutów.

Oczywiście mechanizm refleksji, umożliwia dostęp nie tylko do metod prywatnych, ale również prywatnych atrybutów klasy. Krótki kodzik poniżej, gdyby ktoś potrzebował dostać się do takiego prywatnego pola.

private Integer getPrivateField(SomeClass someClass) 
    throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {

    Field field = SomeClass.class.getDeclaredField("privateInteger");
    field.setAccessible(true); 
 
    return (Integer) field.get(someClass); 
}

public class SomeClass{
    
    private Integer privateInteger;
    ...
}

piątek, 17 września 2010

Testowanie metod prywatnych w javie

Pomijając dysputy o tym, czy w ogóle można, czy też nie można testować metod prywatnych. Zamieszczam przykład jak to zrobić jeśli, ktoś będzie w sytuacji, że po prostu musi to zrobić.

Mamy przykładowo klasę do stestowania:
public class SomeClass{
    ...
    private Boolean someMethod(String s, Integer i){
        ...
    }    
} 

Podczas testów używam mechanizmu refleksji i schematu given/when/then, o którym więcej można posłuchać tutaj. Przykładowa klasa testująca metodę prywatną z klasy SomeClass może być następująca:
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Before;
import org.junit.Test;

public class SomeClassTest {
    
    SomeClass someClass;
    
    @Before
    public void init() {
        someClass = new SomeClass();    
    }
    
    @Test
    public void shouldDoSomethingGood() {        
        //given
        //sekcja przygotowująca
        
        //when
        Boolean result=null;
        try {
            result = invokePrivateMethodSomeMethod("test",10);
        } 
        catch (Exception e) {
            e.printStackTrace();
            fail("Nie oczekujemy wyjątku");
        }        
        //then
        assertThat(result).isTrue();    
    }
    
    private Boolean invokePrivateMethodSomeMethod(String s, Integer i) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{
    
        Class[] args =  {String.class, Integer.class}; 
        //niestety musimy wpisać nazwę metody jako string - niezbyt dobre rozwiązanie w przypadku późniejszego refaktoringu
        Method method = SystemUtils.class.getDeclaredMethod("someMethod", args);
        method.setAccessible(true);
        Object[] argObjects = {s,i};
        return (Boolean) method.invoke(someClass, argObjects);
    }
}

piątek, 10 września 2010

Spring form:checkboxes a JSF h:selectManyCheckbox

Krótka notka dla wszystkich, którzy przesiedli się z JSF'a na Spring'a (wersja 2.5.6) i przyszło im użyć tagu form:checkboxes. Idea obu tagów jest taka sama, czyli jak "przyjemnie" obsłużyć na formularzu wiele checkboxów.

Załóżmy, że mamy encje Employee i Language, które są w relacji wiele-do-wielu.
Aby wyświetlić na formularzu wszystkie checkboxy (języki) z zaznaczonymi tymi, które dany pracownik zna. W JSF używamy:


  


To samo w Spring'u wygląda następująco


Pominę kwestie skąd i jak wstrzykiwane są allLanguages i languages. 

Wszystko teoretycznie powinno działać, ale niestety nie jest tak różowo. Pojawia się następujący błąd:
Failed to convert property value of type [java.lang.String] to required type [java.util.Set] for property languages; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [emp.entity.Language] for property languages[0]: no matching editors or conversion strategy found
Przyczyną błędu jest brak odpowiedniego PropertyEditor'a dla Language. Przykładowy editor dla klasy Language:
public class LanguageEditor extends PropertyEditorSupport {    
    private LanguageManager languageManager;   
    public LanguageEditor(LanguageManager languageManager) {
        super();
        this.languageManager = languageManager;
    }
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        setValue(languageManager.getLanguageById(Long.parseLong(text)));
    }    
    @Override
    public String getAsText() {        
        Language language = (Language) getValue();
        return language == null ? null :  Long.toString(language.getId());
    }    
}

W moim przypadku metoda setAsText używa managera, który pobiera encje Language o danym id z bazy. Trzeba jeszcze tylko dodać tego editora w metodzie initBuilder w kontrolerze który odpowiada za obsługę formularzu:

public class EmployeeEditController extends SimpleFormController{
    ...
    @Override
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
    super.initBinder(request, binder);
    binder.registerCustomEditor(Language.class, new LanguageEditor(languageManager));
    
    .... 

} 

I coś takiego rozwiązuje zgłaszany błąd.

piątek, 9 lipca 2010

Java Integer pool

Mam nadzieje, że nie jestem jednym z ostatnich, którzy się o tym dowiadują, ale kwestia tworzenia Integer'ów w Javie jest dość ciekawa. Prześledźmy kilka przykładów:
//1.
Integer i1 = 12345
Integer i2 = 12345
//(i1==i2) -> false

//2.
Integer i1 = 127
Integer i2 = 127
//(i1==i2) -> true

//3.
Integer i1 = new Integer(127)
Integer i2 = new Integer(127)
//(i1==i2) -> false

A teraz komentarz:
1. Takie przypisanie zmiennej prymitywnej w starszej wersji Javy było w ogóle nie możliwe. Teraz jednak rusza do akcji "opakowywacz" i z typu prymitywnego int robi Integer, dzięki temu obie instrukcje przypisania są poprawne. Porównanie i1==i2 odnosi się oczywiście do referencji. Referencje wskazują na osobne obiekty, dlatego porównanie zwraca wartość false.

2. Tu jest ciekawiej. Dlaczego odwołując się do tego co napisałem powyżej, w tym przypadku jest inaczej? Otóż Java, obiekty typu Integer (również Byte, Short, Long) o wartościach od -128 do 127, przechowuje w specjalnej puli, gdzie obiekty te po prostu nie powtarzają się. Dlatego też referencje wskazują na ten sam obiekt w puli.

3. W ostatnim przykładzie wymuszamy (przez new) otworzenie 2 osobnych obiektów. Stąd wartość porównania wynosi znowu false (niezależnie już od wartości).

poniedziałek, 3 maja 2010

Fix Pack 7.0.0.2 dla Business Process Management = WID działa na full wypas.

Mój wcześniejszy problem, czyli synchronizacji WID'a z WPS'a rozwiązany (!) przez update oprogramowania  do wersji 7.0.0.2., dzięki sugestii mojego mentora.

Instalacja update trwa, żeby nie skłamać, jakoś pół dnia, oczywiście zależy to po części od naszego łącza, bo jest sporo do ściągnięcia. Tak czy inaczej warto było poczekać, bo teraz wszystko działa jak należy. Dodam tylko, że jeśli uruchomiliśmy Instalation Managera z poziomu roota, to po updacie należy wykonać ponownie polecenie:
chown -R andrzej /home/andrzej/IBM
Byłem w stanie uruchomić przykładową aplikacje typu hello world. Taką w stylu Business Process, czyli webservis, który po przesłaniu tytułu, imienia i nazwiska, zwróci nam coś w stylu: "Hello mr andrzej ludwikowski". I tu znowu pochwała w stronę WID'a, który umożliwia przetestowanie naszej aplikacji używając IDE w bardzo przyjemny i przejrzysty sposób. Takie rozwiązania każdy lubi.

piątek, 30 kwietnia 2010

WebSphere Integration Developer - pierwsze wrażenia.

Przez ostatni tydzień miałem przyjemność pobawić się trochę z narzędziem IBM, tj. WebSphere Integration Developer 7. Musze przyznać, że pierwsze wrażenie jest bardzo pozytywne i oby takie pozostało. W końcu narzędzie komercyjne, w którym wiemy za co płacimy. A za co płacimy? Za wygodę między innymi:)

Dla osób, które nie wiedzą czym jest tak do końca WID, to w telegraficznym skrócie, to taki znany wszystkim Eclipse, ale obudowany sporą warstwą funkcjonalności i udogodnień dodanych przez IBM'a. Praca (no może to małe nadużycie, bo aż tyle w nim nie popracowałem) jest bardzo przyjemna, można stworzyć aplikację bazującą na web servisach praktycznie wyłącznie klikając myszką i nie pisząc żadnego kodu. Wszystko obudowane jest paletami z odpowiedniki kontrolkami, która potem może sobie odpowiednio dostosowywać aby zbudować interesująca nas funkcjonalność.

Na pochwałę zasługuje również zbiór dołączonych do WID'a tutoriali i kursów, które napisane są bardzo przystępny sposób i albo tłumaczą ogólnie teorię związaną z procesami biznesowymi, albo pokazują co jak wyklikać aby jakaś przykładowa aplikacja nam zadziałała.

Niestety muszę być obiektywny i dodać łyżkę przysłowiowego dziegciu, nie mogę do tej pory poprawnie zsynchronizować WID'a z WPS'em. Serwer startuje poprawnie (mogę wejść do konsoli admina) jednak jego status jest cały czas na "starting..." przez co nie mogę np. wypróbować testowania serwisów z poziomu WID'a. Mam nadzieję, że problem ten jednak da się jakoś rozwiązać.

czwartek, 22 kwietnia 2010

Instalacja WebSphere Integration Developer 7 na Red Hat 5

Instalacja WID'a nie była aż tak problematyczna, jak się nastawiłem, mając doświadczenia z WPS'em :) Nie mniej, nie obyło się bez problemów, które postaram się przedstawić i omówić w poniższej notce. Instalację przeprowadziłem na oddzielnej kopii Red Hata, (oprogramowanie VmWare pozwala na zainstalowanie wielu systemów operacyjnych), bałem się głównie, że mogę zepsuć całą moją dotychczasową pracę z WPS'em i tak pewnie by się stało, gdybym pracował na jednym systemie. Ale do rzeczy...

Najważniejsze jest odpowiednie przygotowanie systemu przed i po instalacji.
1. Instalator WID będzie komunikował, że brakuje mu biblioteki libstdc++.so.5, aby rozwiązać ten problem nie wystarczy utworzyć linku symbolicznego z libstdc++.so.6 do libstdc.so.5, tak jak to uczyniłem na początku, co potem spowodowało błędy przy uruchamianiu WID'a takie jak:

"Caused by: java.lang.UnsatisfiedLinkError: 
/home/andrzej/IBM/SDPShared/plugins/com.ibm.cic.licensing.lum.linux_7.0.101.v20090605_0444/os/linux/x86/libi4clntjni.so 

(/usr/lib/libstdc++.so.5: version `CXXABI_1.2' not found (required by 
/home/andrzej/IBM/SDPShared/plugins/com.ibm.cic.licensing.lum.linux_7.0.101.v20090605_0444/os/linux/x86/libi4clntjni.so))"

1.1. Musimy zainstalować libstdc++, aby to zrobić najwygodniej należy najpierw zarejestrować swój system w RHN, używając komendy "rhn_register" z poziomu root'a. Rejestracja będzie pytała o login i hasło do konta użytego m.in. do ściągnięcia systemu.


1.2. Następnie wybieramy Appliaction>Add/Remove Software, wyszukujemy i instalujemy compat-libstdc++-33-3.2.3-61

1.3. Warto upewnić się czy biblioteka fizycznie znajduje się w /usr/lib


2. Przechodzimy do instalacji WID'a. Z poziomu root'a wykonujemy umask 0022, a następnie uruchamiamy ./launchpad.sh. Podczas pracy z kreatorem instalacji zmieniłem jedynie katalog instalacji zamieniając /opt/ na /home/andrzej/
2.1. Instalujemy kolejno WID'a, WAS'a, i środowisko testowe (czas ok. 1-1.5 godzin)


3. Po instalacji musimy zwiększyć liczbę uchwytów do plików. Korzystamy z oficjalnej instrukcji:link. W punkcie 7 plik limits.conf znajdował się w moim przypadku w /etc/security. Po wykonaniu instrukcji należy zrestartować system.


4. Ostatnim krokiem jest dodanie uprawnień dla zwykłego użytkownika do katalogu instalacji WID'a (w moim przypadku) /home/andrzej/IBM, używając komendy:
chown -R andrzej /home/andrzej/IBM
5. Po uruchomieniu WID'a w moim przypadku nie została wczytana żadna domyślna perspektywa, nie wiem dlaczego, ale wystarczy ręcznie przełączyć na jakąś z perspektyw i już możemy pracować.

środa, 14 kwietnia 2010

Tutorial jak uruchomić projekt Seam (bazujący na JPA) w Websphere Application Server v 7

Moim głównym zadaniem było, uruchomienie projektu Seam, korzystającego z zewnętrznej bazy danych na WPS'ie, biorąc pod uwagę fakt, że WPS jest nakładką na WAS'a, oraz to że na początku nie mogłem uruchomić profilu WPS'owskiego, napisałem (łącznie z tym) 3 tutrialne potrzebne do uruchominia Seam'a na WAS'ie. Jednakże tutoriale te są w równym stopniu poprawne w przypadku uruchomienia Seam na WPS'ie, jedyna różnica jest taka, że konsola administratora WPS posiada trochę więcej opcji niż ta WAS'owska.

Co potrzebujemy?
1. Seam w wersji 2.1.2.GA: link  - jest to nowsza wersja Seam'a, w poprzednich tutorialach używałem wersji 2.0, jednakże różnice związane z tym tutorialem są tylko takie, że seam-gen zada o kilka pytań więcej, na które odpowiadamy domyślnymi odpowiedziami.
2. Projekt wygenerowany przez seam-gen, na podstawie bazy danych, patrz: link
3. Zapoznanie się oraz wykonanie wcześniejszego tutoriala dotyczącego brakujących bibliotek: link
4. Zapoznanie się oraz wykonanie wcześniejszego tutoriala dotyczącego utworzenia data source: link


Uruchomienie projektu Seam na WAS'ie:
1. Punktem wyjściowym jest projekt wygenerowany przez Seam-gen, najlepiej wcześniej sprawdzony na JBoss'ie. Projekt bazujący na JPA, czyli typu war.
2. Edytujemy plik resources/META-INF/persistence-dev.xml:
 - zmieniamy wartość między tagami < jta-data-source> i wpisujemy tam nazwę JNDI data source, którego wcześniej utworzyliśmy w moim przypadku jdbc/MySql_cms
< jta-data-source>jdbc/MySql_cms< /jta-data-source>
 - dodajemy / edytujemy właściwości hibernate, tak aby otwrzymać:
< properties>
         < property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
         < property name="hibernate.hbm2ddl.auto" value="update"/>
         < property name="hibernate.show_sql" value="true"/>
         < property name="hibernate.format_sql" value="true"/>
         < !-- Only relevant if Seam is loading the persistence unit (Java SE bootstrap) -->
         < property name="hibernate.transaction.manager_lookup_class"            value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
< /properties>
- UWAGA!! W kodzie powyżej są spacje w tagach XML, należy je usunąć, jeśli chcemy wkleić do pliku.
3. Używając polecania "ant archive" w katalogu głównym projektu, kompilujemy projekt i tworzymy m.in. plik .war.
4. Uruchamiamy WAS'a /WPS'a i przechodzimy do konsoli administratora, wybieramy Application>App Types> Websphere E A, oraz wybieramy Install.







5. W następnym oknie wybieramy plik .war który utworzyliśmy (znajduje się on w katalogu dist naszego projektu). Klikamy next, w następnym oknie wybieramy Fast path i dajemy również next.
6. Kreator instalacji zostawiamy bez zmian, tylko w przedostatnim oknie dodajemy nazwę naszego projektu, klikany next, a następnie finish, na końcu zapisujemy zmiany na serwerze:







7. Wybieramy nasz projekt z listy zainstalowanych projektów, wybieramy "Manage modules", następnie klikamy na nazwę naszego projektu z zmieniamy ustawienia class loadera na: "Classes loaded with local class loader first (parent last)"
















8. Podobnie jak w punkcie 7. postępujemy po wyborze "Class loading and update detection".










9. Dodajemy przygotowane wcześniej Shared libraries do naszego projektu. Wybieramy "Shared library references", następnie zaznaczamy nazwę naszej aplikacji i klikamy na "Reference shared libraries", dodajemy "Jboss_libs" do okna po prawej i dajemy OK.









10. Zapisujemy wszystkie zmiany na serwerze. Zaznaczamy nasz projekt na liście i klikamy na start.








11. Projekt powinien się poprawnie uruchomić i jest dostępny pod adresem:
http://localhost:9080/websphere_war_test/index.html
Wymienione wcześniej 2 tutoriale, czyli http://aludwikowski.blogspot.com/2010/04/tutorial-jak-dodac-shared-libraries-do.html, http://aludwikowski.blogspot.com/2010/04/tutorial-jak-dodac-baze-danych-mysql-do.html, razem z tym, tworzą tak na prawdę jeden tutorial, pokazujący jak od początku do końca uruchomić projekt wygenerowany przez seam-gen (używający JPA) na Websphere Application Server.

wtorek, 13 kwietnia 2010

Eclipse problem z "jvm terminated exit code=-1"

W końcu znalazłem rozwiązanie dręczącego mnie od jakiegoś czasu problemu. Pracuje nad pewnym projektem w Eclipse od pół roku i wszystko działało sprawnie aż pewnego dnia przy uruchomieniu Eclipsa dostaję komunikat:

jvm terminated exit code=-1




Rozwiązania podawane w internecie raz działały raz nie, przeinstalowałem nawet Jave, wszystko na nic, bo i tak po jakimś czasie dostawałem, ku mojej irytacji, ten komunikat. Okazało się, że wystarczyło zedytować plik eclipse.ini, i zmniejszyć ilość pamięci dla launchera z 256 na 128:

plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-product
org.eclipse.epp.package.jee.product
--launcher.XXMaxPermSize
128M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
128m
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms40m
-Xmx512m
Nie wiem w sumie z czego to wynika, ponieważ tak jak mówiłem, przez pół roku wszystko działało cacy. Tak czy inaczej mam nadzieje, że to rozwiązanie pomoże na dobre.

poniedziałek, 12 kwietnia 2010

Tutorial jak dodać bazę danych Mysql do DataSource w Websphere Application Server v 7 ?

  Krótki tutorial jak dodać bazę danych MySql, do WAS'a.

Co potrzebujemy?
1. Sterownik JDBC do MySql'a: link.
2. Zainstalowany serwer MySql z utworzoną bazą danych, ten punkt pozostawiam czytelnikowi.

Dodajemy sterownik do "JDBC providers".
1. Uruchamiamy WAS'a, następnie przechodzimy do Resources>JDBC>JDBC providers i wybieramy New.








2. Uzupełniamy odpowiednio formularz. W "Implementation class name" powinniśmy wpisać:
 com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource









3. W następnym oknie podajemy ścieżkę do sterownika JDBC, czyli w moim przypadku.
 /home/andrzej/Desktop/tools/mysql-connector-java-5.1.12/mysql-connector-java-5.1.12-bin.jar
4. Kończymy pracę z kreatorem klikając Finish, oraz zapisujemy zamiany w konfiguracji serwera.

Dodajemy bazę danych do "Data Source".

1. Mając dodany sterownik JDBC, możemy przystąpić do dodania bazy danych. Przechodzimy do Resources>Data source i klikamy New








2. Wypełniamy odpowiednio pola, w moim przypadku nazwa bazy danych to "cms", stąd takie końcówki, oczywiście możemy wypełnić te pola wedle uznania.







3. Wybieramy naszego dostawcę JDBC







4. W następnym oknie wartość dla "Data store helper class name" powinna być ustawiona na:
com.ibm.websphere.rsadapter.ConnectJDBCDataStoreHelper
5. Następne okno pozastawiamy bez zmian, kończymy pracę z kreatorem i zapisujemy zmiany na serwerze.
6. Klikamy na "MySql_cms" na liście "Data source", następnie z podmenu "Additional properties" po prawej stronie wybieramy "Custom properties". Musimy znaleźć i zedytować kilka zmiennych, tj.
databaseName = cms?autoReconnect=true
user = admin
password = admin
port = 3306
serverName = localhost
Wszystkie wartości powinny być typu: java.lang.String. oraz dostosowane do odpowiedniej konfiguracji bazy danych. Jeśli port jest defaultowy to chyba można pominąć tą wartość.









7. Zapisujemy zmiany na serwerze i testujemy połączenie:









Jest to kolejny tutorial będący przygotowaniem do uruchomienia aplikacji Seam na WAS'ie

Tutorial jak dodać "Shared Libraries" do Websphere Application Server v 7

Szybki tutorial jak dodać "Shared Libraries" do WAS'a, dodawane biblioteki będą potrzebne do uruchamiania aplikacji Seam'owskich na WAS'ie, używając JBoss'a nie musimy martwić się o te biblioteki, natomiast w WAS'ie musimy je ręcznie dodać do serwera, lub do samej aplikacji. Tutorial jest oczywiście uniwersalny i możemy dodać inne biblioteki, jednak moim głównym celem jest przystosowanie WAS'a do aplikacji Seam'owskich.

Lista potrzebnych bibliotek, których wymaga projekt Seam używający JPA (!):
  • hibernate.jar
  • hibernate-annotations.jar
  • hibernate-commons-annotations.jar
  • hibernate-entitymanager.jar
  • hibernate-validator.jar
  • commons-collections.jar
  • jboss-common-core.jar
  • antlr.jar
  • cglib.jar
  • asm.jar
  • dom4j.jar
  • javassist.jar
  • concurrent.jar
1. Uruchamiamy WAS'a i przychodzimy do konsoli administratora.
2. Wybieramy Environment>Shared Libraries, oraz klikamy New






3. Wybieramy nazwę, oraz dodajemy ścieżki do poszczególnych .jar'ów, oddzielając je enterem. UWAGA nie możemy oddzielać bibliotek znakami ";" lub ":".









4. Zapisujemy zmiany w konfiguracji serwera.









5. Gotowe ! Oczywiście aby korzystać z tych bibliotek musimy je jeszcze dodać do wdrażanej aplikacji, ale o tym za jakiś czas.

niedziela, 11 kwietnia 2010

Przygotowanie profilu na Websphere Process Server

Wspomniane we wcześniejszym poście problemy, wynikały z zupełnie innych kwestii, niż w początąkowym założeniu, czyli problemamy z SQLem. Problem stanowił inny wyjątek, czyli:

[4/8/10 10:28:56:221 PDT] 00000000 ConnectionEve A J2CA0056I: The 
Connection Manager received a fatal connection error from the Resource 
Adapter for resource jdbc/WPSDB. The exception is: java.sql.SQLException: 
Meta-data for Container 
[email protected] could not be 
accessed:java.sql.SQLException: Meta-data for Container 
[email protected] could not be 
accessed:java.sql.SQLException: Java exception: 
'/home/andrzej/ibm/WebSphere/ProcServer/profiles/ProcSrv02/databases/WPRCSDB/seg0/c290.dat 
(Too many open files): 
java.io.FileNotFoundException'.:java.io.FileNotFoundException: 
/home/andrzej/ibm/WebSphere/ProcServer/profiles/ProcSrv02/databases/WPRCSDB/seg0/c290.dat 
(Too many open files)
Rozwiązaniem tego problemu jest zwiększenie limitu otwieranych plików używając konta roota (polecenie ulimit -n 90000 w pliku /root/.bashrc), oraz uruchomienie serwera również z poziomu root'a. Rozwiązanie można znaleźć na blogu kolegi Rafała: link.

piątek, 9 kwietnia 2010

Przygotowanie do deployowania aplikacji seam na WPS/WAS

Przygotowania do uruchomienia przykładowych aplikacji Seam na Websphere Process Server, niestety nie odbyły się bez problemów. Po utworzeniu profilu (typu stand-alone) na WPS'ie serwer uruchamia się z błędami, takimi jak:
[4/8/10 10:28:56:378 PDT] 00000000 WSRdbManagedC W DSRA0180W: Exception detected during ManagedConnection.destroy(). The exception is:

com.ibm.ws.exception.WsException: DSRA0080E: An exception was received by the Data Store Adapter. See original exception message: No current connection.. with SQL

State : 08003 SQL Code : 40000
at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
Przypuszczam, że skutkiem tych błędów są kolejne błędy przy uruchomieniu konsoli administratora. Niestety po przeszukaniu ton materiałów wypstrykałem się pomysłów jak naprawić ten błąd. Dodam, że pojawią się one już na świeżutkiem WPS-ie, gdzie nic nie było zmieniane i konfigurowane.

Skoro WPS ma pod sobą WAS'a, postanowiłem używać profilu WAS'owskiego, na którym serwer uruchamia się bez najmniejszych problemów. Pierwszy próby deployowania aplikacji seam'owskich zakończyły się ni to sukcesem ni to porażką, ponieważ bazując na oficjalnej instrukji: link, udało mi się uruchomić aplikacje jpa, niestety przykład z jee5/booking nadal nie chce działać. Generalnie sama instrukcja mogła by być napisana w trochę bardziej obszerniejszy sposób, ponieważ wiele aspektów działania seam na was nadal pozostaje dla mnie czarną plamą, która zamierzam w miarę zmniejszać w następnym tygodniu.....

środa, 7 kwietnia 2010

Instalacje IBM WPS na Red Hat - "silent mode"

Drugą opcją instalacji WPS'a jest instalacja w tzn. "silent mode". Czyli cała instalacja odbywa się po cichu, bez żadnych kreatorów, itd. Wystarczy, że zmodyfikujemy odpowiednio dwa pliki.

1. DVD_root or extract_root/responsefiles/wbi/template_response.xml
i
2.
DVD_root or extract_root/responsefiles/wbi/run_templates

Jeśli zależy nam na standardowej instalacji, to w moim przypadku zmieniłem wszystkie wystąpienia "/opt/" na "/home/andrzej/" w obu plikach oczywiście. Dodatkowo jeśli zależy nam na utworzeniu defaultowego profilu, to należy odkomentować i uzupełnić odpowiedni linie z pliku template_response.xml.

< installlocation="'/home/andrzej/ibm/WebSphere/ProcServer'" id="'IBM">
< data key="'eclipseLocation'" value="'/home/andrzej/ibm/WebSphere/ProcServer'/">
< data key="cic.selector.nl" value="en">
< data key="user.cic.imported,com.ibm.websphere.ND.70" value="WAS">
< data key="'user.bpm.admin.username'" value="'andrzej'/">
< data key="'user.bpm.admin.password'" value="'haslo'/">
< / profile >


Uruchomienie instalacji odbywa się poprzez uruchomienie pliku: run_templates. Więcej na ten temat można przeczytać w oficjalnej dokumentacji: link.

UWAGA!!
Przygotowanie systemu powinno być identyczne jak to było opisane w poprzednim poście: link. Warto też uruchomić całą instalację, czyli plik run_templates, z poziomu root'a, żeby uniknąć problemów z przywilejami.

niedziela, 4 kwietnia 2010

Instalacja IBM WebSphere Process Server 7 na Red Hat Enterprise Linux 5

Kilka podpowiedzi jak zainstalować IBM WebSphere Process Server na Red Hat Enterprise Linux 5 dla takich linuxowych słabiaków jak ja.

0. Nie wiem czy było to konieczne, raczej nie, ale jako rozgrzewkę polecam zainstalowanie sobie Java JDK (wraz z JRE), oraz podpięcie pod przeglądarkę internetową, JDK prędzej czy później i tak będzie nam potrzebne. Aby podpiąć JRE pod FF polecam istrukcję na stornie: link. UWAGA! W moim przypadku, przy tworzeniu linku, zamiast katalogu ns7-gcc29, należało wybrać ns7. Jeśli nie posiadamy katalogu plugins w głównym katalogu FF, to należy go utworzyć ręcznie.

1. Przed przystąpieniem do instalacji WPS'a należy odpowiednio przygotować Red Hat'a. Postępujęmy wg. oficjalnej instrukcji: link. Uwagi do poszczególnym punktów:
1. wybieramy umask 002 - wybrałem instalacje na zwykłym koncie użytkownika.
Większość instrukcji jest niekonieczna jeśli pracujemy na "świeżym" linuxie.
UWAGA! W przypadku Red Hat'a musimy dodatkowo wyłączyć SELinux - jest to system ochronny systemu (nie wiem do końca jak działa więc nie będę się rozpisywał), który w pewnym momencie może zablokować nam instalację WPS'a.
Aby wyłączyć SELinux, należy zedytować plik "/etc/selinux/config"

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=enforcing
# SELINUXTYPE= can take one of these two values:
# targeted - Only targeted network daemons are protected.
wystarczy zmienić SELINUX=enforcing na SELINUX=permissive i zrestartować system.

2. Z tak przygotowanym systemem instalacja przebiegła u mnie bez żadnych błędów i problemów. Bazowałem na oficjalnej instrukcji: link. Wybieramy opcje "Nonadministrative or nonroot installation." A dalej leci już z górki.

czwartek, 1 kwietnia 2010

Seam + Eclipse tutorial.

Postanowiłem napisać ostatni tutorial z cyklu "początki z seamem", aby dopełnić poprzednie 2, czyli seam - pierwsze kroki i seam-gen w akcji oraz aby mój kolega (który zaczął zajmować się seamem) w końcu dał mi święty spokój:P

Ideą tutoriala jest zintegrowanie aplikacji wygenerowanej przez seam-gen z IDE w tym przypadku z eclipsem.

Co potrzebujemy?
1. Projekt seam, jak to zrobić można przeczytać w wcześniejszym tutorialu seam-gen w akcji
2. Eclipse (najlepiej wersja EE): link

Jak podłączyć projekt seam pod Eclipsa?
Procedura jest dość prosta i nie wymaga wiele wysiłku.

1. Wybieramy File>import
2. Z zakładki General wybieramy Existing Projects into Workspace i dajemy Next
3. Natępnym krokiem jest wybranie katalogu w którym mamy projekt (Browse)
4. Klikamy Finish

I to by było na tyle, w końcu przechodzimy z poziomu konsoli do kontentego środowiska i rozwijamy nasz projekt wedle uznania.

UWAGI:
1. Podczas pracy nad projektem Eclipse używa pliku build.xml do tzn. hot-deploy'ingu, kiedy zapisujemy dany plik, np. widoku, Eclipse automatycznie wykonuje polecenie seam explode (czy też ant explode), od tej pory nie musimy wykonywać go z poziomu konsoli. UWAGA hot-deploy nie działa w przypadku części plików konfiguracyjnych i innych, dlatego od czasu do czasu potrzebny będzie restart serwera. Więcej na ten temat można poczytać w specyfikacji seam.
2. Warto dodać sobie serwer JBoss do IDE, żeby nie było potrzeby odpalania go z poziomu konsoli. W tym celu wykonujemy: File>new>other>server, wybieramy rodzaj serwera oraz wskazujemy jego katalog główny.
3. Dobrym pomysłem może być zainstalowanie wtyczki JBoss tools do Eclipsa, która pozwala na wizualizację wielu plików konfiguracyjnych, widoków, itd. Najprawdopodobniej pozwala również na używanie seam-gen z poziomu IDE, aczkolwiek nie zgłębiłem tej kwestii.

czwartek, 25 marca 2010

Seam-gen + DB2

Udało mi się w końcu połączyć działanie seam-gen z DB2, co nie było takim prostym zadaniem jak myślałem. Ogólnie DB2, jak na komercyjne rozwiązanie, sprawia wiele problemów dla użytkownika, który ma pierwszy raz z nim styczność. Żeby wygenerować projekt używając seam-gen na podstawie bazy danych w DB2 (v. 9.7), musimy zmienić kilka rzeczy:

1. Potrzebujemy odpowiedni sterownik JDBC, który możeby znaleźć standardowo w: "C:\Program Files\IBM\SQLLIB\java\db2jcc.jar"
2. W pliku konfiguracyjnym seam-gen musimy nanieść kilka zmian:
2.1. hibernate.connection.driver_class=com.ibm.db2.jcc.DB2Driver
2.2. hibernate.default_schema=ANDRZEJ
//oczywiście powinien być to odpowiednia wartość dla danej bazy
2.3. użytkownika i hasło pozostawić puste, ponieważ nie są wymagane przy łączeniu się z localhost'a
2.4. hibernate.connection.url=jdbc\:db2\:NAZWA_BAZY //jeśli używamy kreatora, podajemy oczywiście: jdbc:db2:NAZWA_BAZY
2.5. driver.jar=c\:/java_libs/db2jcc.jar
3. Po uruchomieniu polecenia: seam generate, posypie się jeden błąd, który niema znaczenia i cała operacja powinna zakończyć się sukcesem
4. Co mnie najbardziej zdziwiło, to fakt, że tak wygenerowany projekt w moim przypadku nie chciał się deployować na serwerze z powodu błędu:
2010-03-25 11:45:27,781 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[localhost].[/DB2Test3]] Exception sending context initialized event to listener instance of class org.jboss.seam.servlet.SeamListener
org.jboss.seam.InstantiationException: Could not instantiate Seam component: DB2Test3EntityManagerFactory
Powodowanego przez:
Caused by: org.hibernate.HibernateException: Wrong column type: CO_CD, expected: varchar(3)
Rozwiązaniem problemu była zmiana typu kolumn w bazie z CHARACTER na VARCHAR, przypuszczam, że wiąże się to z jakimiś niepasującymi dialektami, i bardzo możliwe, że istnieje lepsze rozwiązanie, aczkolwiek na chwilę obecną nie jest mi ono znane.

Seam-gen w akcji

Od 2 tygodniu tonę w dokumentacji/artykułach dotyczących Seam'a, ciężko by było to wszystko przyswajać bez motywacji. Dla tych, którzy jeszcze nie przekonali się do tego, że warto poczytać trochę o tym Seam'ie, proponuje mały tutorial o seam-gen – coś co w moim wypadku przeważyło szalę: warto, czy nie warto czytać o Seam'ie.

Seam-gen ogólnie przywrócił moją wiarę w JaveEE, w której od zawsze widziałem ogromny potencjał, ale nie mogłem pojąć, dlaczego tworzenie w niej czegokolwiek jest tak trudne, a przede wszystkim czasochłonne? Ktoś kto używał np. cakePHP wie o czym mówię, ponieważ używając caka, możemy zrobić w pełni działającego CRUD'a w kilka minut. I tą lukę w Javie wypełnia Seam-gen – narzędzie do tworzenia CRUD'a na podstawie bazy danych. Koniec gadania, przejdźmy do rzeczy.

Co potrzebujemy:

1. Wszystko to co było potrzebne w poprzednim tutorialu (wybieramy 1 serwer który bardziej nam odpowiada w tym przypadku będę bazował na JBoss'ie)
2. Serwer bazy danych, proponuje zainstalować MySql, najlepiej z jakimś przyjemnym supportem, żebyśmy nie musieli go obsługiwać z poziomu konsoli. Instalacja wamp'a załatwi sprawę: link
3. Sterownik JDBC do MySql'a, link

Przygotowanie:

- Wszystko co to zostało napisane we wcześniejszym tutorialu.
- Przygotowanie MySql:
- należy utworzyć nową bazę danych, wraz z przykładowymi tabelami – pozostawiam to czytelnikowi.

Odpalenie Seam-gen:

1. Przechodzimy do katalogu głównego Seam'a i edytujemy plik: build.properties, gdzie umieszczamy ścieżkę do katalogu głównego JBoss'a w moim przypadku:
jboss.home=C:\\jboss-4.2.3.GA
2. Uruchamiany kreator konfiguracji seam-gen:
C:\Andrzej\seam\jboss-seam-2.0.2.SP1>seam setup
w tym momencie kreator konfiguracji zada nam serię pytań, których wynikiem będzie plik konfiguracyjny znajdujący się w seam-gen/build.properties. Generalnie możemy edytować go ręcznie lub używać kreatora.

3. W nawiasach kwardatowych znajdują się defaultowe (lub zapamiętane z wcześniejszego użycia) odpowiedzi – możemy je zatwierdzić naciskając po prostu ENTER.

Pyt: [input] Enter your Java project workspace (the directory that contains your Seam projects) [C:/Projects] [C:/Projects]
Odp: c:/eclipse/workspace
//Używam '/' zamiast '\\' - mniej pisania.

Pyt: [input] Enter your JBoss home directory [C:/Program Files/jboss-4.2.2.GA] [C:/Program Files/jboss-4.2.2.GA]
Odp: C:/jboss-4.2.3.GA
//ścieżka do katalogu głównego z JBoss

Pyt: [input] Enter the project name [myproject] [myproject]
Odp: NowyProjekt

//Wybieramy nazwe dla projektu:

Pyt: [input] Do you want to use ICEFaces instead of RichFaces [n](y, [n])
Odp: ENTER

Pyt: [input] Select a RichFaces skin [blueSky] ([blueSky], classic, ruby, wine, deepMarine, emeraldTown, sakura, DEFAULT)
Odp: ENTER

Pyt: [input] Is this project deployed as an EAR (with EJB components) or a WAR (with no EJB support) [ear] ([ear], war)
Odp: war
// wybieramy war, jeśli chcemy korzystać z JavaBeans, zamiast EJB, oraz jeśli chcemy później używać tzn. „hot deployment”

Pyt: [input] Enter the Java package name for your session beans [com.mydomain.NowyProjekt] [com.mydomain.NowyProjekt]
Odp: com.mydomain.NowyProject.action

Pyt: [input] Enter the Java package name for your entity beans [com.mydomain.NowyProject.action] [ com.mydomain.NowyProject.action]
Odp: com.mydomain.NowyProject.model

Pyt: [input] Enter the Java package name for your test cases [com.mydomain.NowyProject.action.test] [com.mydomain.NowyProject.action.test]
Odp: com.mydomain.NowyProject.test

Pyt: [input] What kind of database are you using? [hsql] ([hsql], mysql, oracle,postgres, mssql, db2, sybase, enterprisedb, h2)
Odp: mysql

Pyt: [input] Enter the Hibernate dialect for your database [org.hibernate.dialect.MySQLDialect] [org.hibernate.dialect.MySQLDialect]
Odp: ENTER

Pyt: [input] Enter the filesystem path to the JDBC driver jar [../lib/hsqldb.jar][../lib/hsqldb.jar]
Odp: C:/java_libs/mysql-connector-java-5.1.12-bin.jar

Pyt: [input] Enter JDBC driver class for your database [com.mysql.jdbc.Driver] [com.mysql.jdbc.Driver]
Odp: ENTER

Pyt: [input] Enter the JDBC URL for your database [jdbc:mysql:///test] [jdbc:mysql://test]
Odp: jdbc:mysql://localhost/cms
//url do bazki, w moim przypadku baza ma nazwę „cms”

Pyt: [input] Enter database username [sa] [są]
Odp: root

Pyt: [input] Enter database password [] []
Odp: ENTER //ponieważ nie mam ustawionego hasła

Pyt: [input] Enter the database catalog name (it is OK to leave this blank) [] []
Odp: ENTER

Pyt: [input] Are you working with tables that already exist in the database? [n] (y, [n])
Odp: y

Pyt: [input] Do you want to drop and recreate the database tables and data in import.sql each time you deploy? [n] (y, [n])
Odp: n

Kreator powinien zakończyć swoje działanie poprawnie:
BUILD SUCCESSFUL

Total time: 15 minutes 56 seconds

Możemy podejrzeć jak wygląda plik konfiguracji seam-gen: seam-gen/build.properties.

4. Kolejnym krokiem jest utworzenie bazowej struktury projektu, używając polecenia: seam create-project
C:\Andrzej\seam\jboss-seam-2.0.2.SP1>seam create-project
5. Wykonując polecenie: seam generate dokonujemy inżynierii odwrotnej i na podstawie bazy generowane są odpowiednie widoki oraz klasy.
C:\Andrzej\seam\jboss-seam-2.0.2.SP1>seam generate
6. Ostatnim poleceniem jest: seam explode, które pozwoli nam zdeployować projekt i być oczarowanym tym jak ładnie seam-gen wygenerował nam CRUD'a
C:\Andrzej\seam\jboss-seam-2.0.2.SP1>seam explode
7. Uruchamiamy JBoss'a i sprawdzamy jak wygląda nasz projekt w przeglądarce:
http://localhost:8080/NowyProjekt/

W następnej notce postaram się napisać jak podłączyć tak wygenerowany projekt pod Eclipsa lub NetBeansa

sobota, 20 marca 2010

Seam - pierwsze kroki.

Biorąc pod uwagę swoje własne lenistwo, oraz to, że po prostu lubię jak mi ktoś pewne rzeczy wytłumaczy łopatologicznie, postanowiłem, że napisze krótki tutorial jak uruchomić przykładowe aplikacje z seam'a (mimo wcześniejszego posta, w którym w sumie napisałem gdzie najlepiej szukać pomocy). Tutorial obejmuje 2 rodzaje serwerów Tomcat i JBoss, ale możemy wybrać jeden z nich. Dla wszystkim miłośników Tomcat'a (sam do nich należę) polecałbym jednak spróbowanie JBoss'a.

Co potrzebujemy?
1. Seam w wersji 2.0.2.SP1: link
2. Tomcat w wersji 6.x: link
3. lub JBoss w wersji 4.2.3: link
4. Ant w wersji 1.8: link

Przygotowanie:
należy ściągnąć wyżej wymienione oprogramowanie i rozpakować. Oczywiście zakładamy, że mamy zainstalowane JDK w wersji minimum 5. oraz ustawione są zmienne środowiskowe JRE_HOME i JAVA_HOME w zależności od tego gdzie zainstalowaliśmy Javę. Jak to zrobić można przeczytać m.in. tu. Aby sprawdzić czy zmienna jest prawidłowo ustawiona możemy ją wyświetlić używając komendy set:

C:\Documents and Settings\andrzej>set JRE_HOME
JRE_HOME=C:\Program Files\Java\jre6
Po ustawieniu zmiennej, bardzo często trzeba uruchomić ponownie konsolę, żeby było ją widać - nie mam pojęcia dlaczego.

Przygotowanie Ant'a:
po ściągnięciu Ant'a i rozpakowaniu musimy ustawić zmienną środowiskową ANT_HOME na katalog w którym mamy Ant'a (%ANT_HOME%\bin\ant.bat), w moim przypadku:
C:\Documents and Settings\andrzej>set ant
ANT_HOME=C:\apache-ant-1.8.0
Musimy również dodać do zmiennej PATH (oczywiście po średniku) "%ANT_HOME%\bin", czyli w moim przypadku: "C:\apache-ant-1.8.0\bin".

Przygotowanie Tomcat'a:
Tomcat sam w sobie nie wymaga wielu przygotowań, oprócz prawidłowej instalacji Javy, aczkolwiek jeśli chcemy przetestować przykłady korzystające z EJB, musimy zainstalować Embedded JBoss, bardzo dobrą instrukcję jak to zrobić, możemy znaleźć tutaj. Dla tych którzy mają u siebie Java EE 6, należy nie zapomnieć o dodaniu jednej linii na początku pliku catalina.bat:
set JAVA_OPTS=%JAVA_OPTS% -Dsun.lang.ClassLoader.allowArraySyntax=true
Przygotowanie JBoss'a:
none

Odpalanie przykładowych aplikacji Seam:
1. Przechodzimy do katalogu głównego seam (nie pomylić plików!, ponieważ pliki build są praktycznie w każdym pod katalogu) i edytujemy plik: build.properties dodając w nim wspomniane wcześniej) ścieżki do katalogów głównych JBoss'a i Tomcat'a, w moim przypadku:
jboss.home=C:\\jboss-4.2.3.GA
tomcat.home=C:\\apache-tomcat-6.0.24
2. Przechodzimy do folderu "examples" i wybieramy jeden z przykładów, standardowo niech to będzie: "registration", przychodzimy do folderu wybranego przykładu z poziomu linii komend wykonujemy:

2.A.1. W przypadku JBoss'a polecenie ant explode:
C:\Andrzej\seam\jboss-seam-2.0.2.SP1\examples\registration>ant explode
2.A.2. Następnie uruchamiany JBossa z linii komend:
C:\jboss-4.2.3.GA\bin>run.bat
2.A.3. Odpalamy przeglądarkę i uruchamiamy nasz przykład:
http://localhost:8080/seam-registration/
2.B.1. W przypadku Tomcat'a (jeśli wczęśniej uruchamialiśmy przykład na JBoss'ie to musimy zatrzymać serwer oraz w katalogu przykładu wykonać ant clean):
C:\Andrzej\seam\jboss-seam-2.0.2.SP1\examples\registration>ant tomcat.deploy
2.B.2. Uruchamiamy Tomcat'a:
C:\apache-tomcat-6.0.24\bin>startup.bat
2.B.3. Odpalamy przeglądarkę i uruchamiamy nasz przykład (link jest trochę inny niż w przypadku JBoss'a, należy pamiętać o przedrostku "jboss-"):
http://localhost:8080/jboss-seam-registration/
I to by było na tyle, aby odpalić inne przykłady postępujemy analogicznie, zmieniając odpowiednio nazwę przykładu, tam gdzie jest to potrzebne.
W następnym poście postaram się napisać coś o seam-gen - bardzo przydatne narzędzie.
Tymczasem pozdrawiam.

piątek, 12 marca 2010

ESI - praktyki edukacje w IBM

Od następnego tygodnia (tj. 12.03.2010) zaczynam już na poważnie praktyki w firmie IBM, uczestnicząc w tzw. programie ESI (Educational Students Intership).

Tematyka moich praktyk będzie głównie krążyła wokół aspektów związanych z technologią JavaEE a konkretnie z frameworkiem SEAM.

Moim mentorem podczas praktyk będzie Jacek Laskowski, a najnowsze informacje o postępach będzie można śledzić na twitterze oraz bliperze.

Jeśli chodzi o ten tydzień to głównie przygotowywałem swoją maszynę do pracy, co wymagało ściągnięcia całej masy instalek, bibliotek, tutoriali. Oczywiście nie byłbym sobą gdybym już czegoś nie zaczął robić, więc wstępnie zapoznałem się z frameworkiem SEAM, ustawiłem odpowiednio serwer toccat 6.0, aby mógł współpracować z SEAM. Ogólnie tomcat bez żadnych dodatkowych ustawień może współpracować z SEAM aczkolwiek jeśli chcemy odpalić przykłady korzystające z EJB, to musimy doinstalować do niego Embedded JBoss, instrukcje jak to wykonać możemy znaleźć tu:
http://community.jboss.org/wiki/EmbeddedAndTomcat

W swoich dotychczasowych testach wykorzystywałem SEAM’a w wersji: 2.0.2.SP1, na oficjalnej stronie SEAM’a jest już nowsza wersja aczkolwiek zauważyłem, że większość tutoriali w internecie jest przygotowanych pod tą wersje.
Przed przystąpieniem do odpalania przykładów z SEAM, radziłbym oprócz zapoznania się z oficjalną dokumentacją:
http://docs.jboss.com/seam/latest/reference/en-US/html/index.html
zapoznać się również z plikiem readme.txt – znajdującym się w folderze: seam/examples. Jest tam najlepiej wytłumaczone jak odpalać wszystkie przykłady dla tomcat’a i jboss’a używając ant’a. Jeszcze jeden mały tips z mojej strony dla użytkowników windowsa, plik build.properties (w katalogu seam), powinien być uzupełniony o ścieżki do obu serwerów np. w ten sposób:
jboss.home=C:\\Andrzej\\jboss\\jboss-4.2.3.GA
tomcat.home=C:\\apache-tomcat-6.0.24

“\\” - podwójny ukośnik zajął mi sporą część dnia w poszukiwaniu, co jest nie tak.