Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

Witam,

Uporalem sie juz z pula polaczen do systemu zewnetrznego, ale teraz znalazl sie nowy problem i nie wiem co robie nie tak. No ale moze po koleji:

Mam pewna biblioteke (nazwijmy ja bibl), ktora zapewnia mi polaczenie do systemu zewnetrznego. No i powiedzmy ze ma metody polacz(), rozlacz(), wykonajoperacje(jakis parametr).

No to tworze sobie EJB, ktore chce zeby polaczylo sie z systemem zewnetrznym i obslugiwalo wywolanie metody wykonajoperacje(jakis parametr). Robie to tak:

@Stateless
public class KlasaBean implements KlasaLocal {
bibl polaczenie;
public KlasaBean() {
polaczenie.polacz();
}

public void wykonajOperacje (String parametr) {
polaczenie.wykonajoperacje(parametr);
}
public void close() {
polaczenie.rozlacz();
}
}

nastepnie mam interfejs:
@Local
public interface KlasaLocal {
public void close();
public void wykonajOperacje (String parametr);
}


Nastepnie mam WebService:

@WebService()
@Stateless
public class NewWebService {
@EJB
private KlasaLocal ejbRef;

@WebMethod(operationName = "wykonajOperacje")
public void wykonajOperacje(@WebParam(name = "parametr")
String parametr) {
return ejbRef.wykonajOperacje(parametr);
}
}


No i problem teraz polega na tym ze po deployu na serwer aplikacji (JBossAS 5.0.0) Po wykonaniu przez klienta metody WS wykonajOperacje dostaje wyjatek:


javax.xml.ws.soap.SOAPFaultException: java.lang.NullPointerException
at com.sun.xml.internal.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:171)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:94)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:240)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:210)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:103)
at $Proxy31.wykonajOperacje(Unknown Source)
at clientwstest.Main.main(Main.java:25)


Co robie nie tak?
Piotr Wierzbowski

Piotr Wierzbowski IT Architect, Asseco
Poland S.A.

Temat: EJB3 + WS + System zewnetrzny

Tak na oko to prawie wszystko jest źle :).
Próba zrobienia stanowego webserwisu w ten sposób?
Tworzenie połączenia w konstruktorze beana EJB (?!?!?!)?
EJB bezstanowy z atrybutem klasy?
Czy wiesz że każde wywołanie metody EJB może być uruchomione na innej instancji?
Użycie "metody polacz(), rozlacz()" chyba nie za bardzo wskazuje na użycie jakiejkowiek puli, chyba że to tylko tak nazwałeś?

Ale wracając do samego exceptiona to myślę, że jak zajrzysz do logu serwera, a nie klienta, to zobaczysz, że to 'polaczenie' jest nullem, ale to tylko taki strzał...
Co do samej koncepcji to jeśli to jest projekt 'na studia' to nie porywaj się z motyką na słońce tylko zrób ta pule na jakiejś klasie statycznej i pobieraj i zwracaj do puli połączenie w tej samej metodzie, a nie otwierasz połaczenie w jednej instancji w drugiej zamykasz a w trzeciej próbujesz użyć zamknietego połączenia.
EJB jest przesadą, gdy nie musisz miec transakcji, pul obiektów, klastrowania, itp.
Taka rada absolwenta ;).
Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

>Czy wiesz że każde wywołanie metody EJB może być uruchomione na innej instancji?
Wiem i dlatego wlasnie chcialem w konstruktorze juz nawiazywac polaczenie, zeby kazda instancja EJB byla juz polaczona.

>Użycie "metody polacz(), rozlacz()" chyba nie za bardzo wskazuje na użycie jakiejkowiek puli, chyba że to tylko tak nazwałeś?
Metoda polacz() miala byc uruchamiana w konstruktorze, a metoda rozlacz() w destruktorze (@preDestroy ??). W takim przypadku to juz kontener EJB sam zapewni mi pule polaczen (no bo sam stworzy sobie pule instancji EJB - czy moze sie myle)

>EJB bezstanowy z atrybutem klasy?
Hmm no tym atrybutem mial byc uchwyt polaczenia co chyba jest dobrym podejsciem.

No chyba ze takie rozumowanie jest nie do konca poprawne :)
Paweł Grzegorz Kwiatkowski

Paweł Grzegorz Kwiatkowski Architekt
oprogramowania,
Ericsson

Temat: EJB3 + WS + System zewnetrzny

Jak się dobrze przyjrzeć:

bibl polaczenie;

to nie widzę, żebyś gdzieś inicjalizował zmienną "polaczenie". Chyba, że wkleiłeś psuedo-kod.

Jeśli zrobiłeś resource adapter, o którym była mowa w innym wątku, to możesz pobrać referencję z JNDI do obiektu połączenia i nie bawić się w takie rzeczy jak tworzenie połączenia. A jako, że to jest EJB3 to możesz połączenie "wstrzyknąć" adnotacją.
Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

No ale zostawmy narazie ta pule.

Obiekt polaczenie jest oczywiscie przed wywolaniem polaczenie.polacz() inicjowane polaczenie = new biblo();

Co jest nie tak z moim wczesniejszym rozumowaniem?

konto usunięte

Temat: EJB3 + WS + System zewnetrzny

1. nie masz zadnej kontroli nad iloscia statelessow, ktore stworzy kontener (moze ich byc 5 a moze i 50). nie wiesz, ile polaczen bedziesz miec.
2. nie masz zadnej kontroli nad zamykaniem polaczenia - wiele beanow przezyje do konca dni kontenera.
3. jesli stateless, w ktorym masz te polaczenia w polu klasy bedzie robic 100 tysiecy innych rzeczy, to nawet jesli nigdy nie wywola sie wykonajOperacje to i tak polaczenia wisza.
4. zamiast tworzy polaczenie w konstruktorze powinienes to zrobic w metodzie postConstruct (wtedy juz srodowisko beana istnieje i ma sie dobrze - pewnie stad masz null pointera; do tego masz juz wtedy wszelakie injekcje zapewnione).
5. obsluge systemu zewnetrznego lepiej jest opakowac w cos wiekszego i korzystac na zasadzie POJO-fasady - chocby bezposrednio w beanie

najlepiej, tak jak przedmowca mowil - stworzyc sobie klase pomocnicza, czy adapter, przez ktory pojda odwolania do systemu zewnetrznego. masz kontrole, czysty kod itd...
Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

To mi juz troche wiecej wyjasnia.
1. nie masz zadnej kontroli nad iloscia statelessow, ktore stworzy kontener (moze ich byc 5 a moze i 50). nie wiesz, ile polaczen bedziesz miec.
czy istnieje mozliwosc skonfigurowania serwera aplikacji (jboss as w wersji 5) do tworzenia dokladnie okreslonej ilosci instancji EJB?
2. nie masz zadnej kontroli nad zamykaniem polaczenia - wiele beanow przezyje do konca dni kontenera.
Generalnie to mi to bardzo nie przeszkadza bo tak naprawde wszystkie operacje beda wykonywane na systemie zewnetrznym. Serwer aplikacji bedzie postawiony tez tylko pod ta konkretna aplikacje.
3. jesli stateless, w ktorym masz te polaczenia w polu klasy bedzie robic 100 tysiecy innych rzeczy, to nawet jesli nigdy nie wywola sie wykonajOperacje to i tak polaczenia wisza.

Ten EJB bedzie robic wszystkie operacje na systemie zewnetrznym do ktorego bedzie mial polaczenie.
4. zamiast tworzy polaczenie w konstruktorze powinienes to zrobic w metodzie postConstruct (wtedy juz srodowisko beana istnieje i ma sie dobrze - pewnie stad masz null pointera; do tego masz juz wtedy wszelakie injekcje zapewnione).
No i to jest chyba najwazniejsza rzecz jaka mnie nurtowala. W poniedzialek bede mial wiecej czasu to to sprawdze.
5. obsluge systemu zewnetrznego lepiej jest opakowac w cos wiekszego i korzystac na zasadzie POJO-fasady - chocby bezposrednio w beanie
Hmm...chodzi o to, ze ten bean bedzie wszystkie operacje wykonywal na danych pobranych z systemu zewnetrznego. Kazda operacja bedzie odwolywac sie do tego zdalnego systemu. Problem polega na tym, ze wykonanie operacji na systemie zewnetrznym wymaga kilku zabiegow (stworz obiekt klasy, wykonaj metode polacz(), nastepnie metode ustaw itp. dopiero pozniej wykonaj wlasciwa metode i rozlacz()). Gdyby nie chodzilo o szybkosc dzialania to moglbym za kazdym razem sie laczyc i rozlaczac z systemem.

najlepiej, tak jak przedmowca mowil - stworzyc sobie klase pomocnicza, czy adapter, przez ktory pojda odwolania do systemu zewnetrznego. masz kontrole, czysty kod itd...


Reasumujac sytuacja wyglada tak:
Mam biblioteke w postaci pliku jar, ktora zapewnia mi api do polaczen z systemem zewnetrznym i do operowania na nim. Teraz powiedzmy ze dla klienta chce udostepnic czesc funkcji z tego dostarczonego api przez WebServices (troche je po drodze zmodyfikowac ale to malo istotne jest). No i teraz najwazniejsze. Metody udostepnione przez WS maja dzialac szybko (dlatego nie chce za kazdym razem laczyc sie z systemem zewnetrznym).

Klient ------- WS --------- API ----------- system zew

Innymi slowy WS ma byc proxy udostepniajacym czesc funkcji API, ale tak zeby polaczenie miedzy API a systemem zew bylo nawiazane raz, a nie przed wywolaniem kazdej z metod.

Moze moje podejscie z EJB stateless jest bledne i podrzucicie jakies ciekawsze rozwiazanie.
Paweł Grzegorz Kwiatkowski

Paweł Grzegorz Kwiatkowski Architekt
oprogramowania,
Ericsson

Temat: EJB3 + WS + System zewnetrzny

Czyli to EJB tak na dostawkę masz. Na dobrą sprawę to powinno wystarczyć rozwiązanie, które zapewni Ci pulę połączeń.

Przyglądałeś się może temu http://commons.apache.org/pool ?
Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

@Stateless
public class KlasaBean implements KlasaLocal {

public void wykonajOperacje (String parametr) {

}

nastepnie mam interfejs:

@Local
public interface KlasaLocal {

public void wykonajOperacje (String parametr);

}

Nastepnie mam WebService:

@WebService()
@Stateless
public class NewWebService {

@EJB
private KlasaLocal ejbRef;

@WebMethod(operationName = "wykonajOperacje")
public void wykonajOperacje(@WebParam(name = "parametr")
String parametr) {
return ejbRef.wykonajOperacje(parametr);
}
}

ERROR [SOAPFaultHelperJAXWS] SOAP request exception
java.lang.NullPointerException

Czyzby wstrzykniecie
@EJB
private KlasaLocal ejbRef;

nie dzialalo poprawnie? Wywala sie przy wywolaniu ejbRef.wykonajOperacje(parametr);

Ja juz jestem taki skolowany ze nie wiem co jest nie tak w tak prostym przykladzie
Szymon Błądek

Szymon Błądek Software Engineer at
I-BS.PL

Temat: EJB3 + WS + System zewnetrzny

Dobra rozwiazalem wiekszosc swoich problemow.

Odpalilem wszystko na glassfish v2 i juz ejb dziala jak powinno.

W JbossAS 5 nie chcialo dzialac wstrzykiwanie (jest to bug) i ogolnie nie tworzyl mi puli EJB.

Następna dyskusja:

Jaki framework J2EE pod duz...




Wyślij zaproszenie do