10 maja 2009

Na kłopoty...Groovy!

Ostatnimi czasy zauważyłem u siebie pewien trend ku znacznemu wykorzystaniu Groovy do namierzania miejsc, które wymagają poprawy. Po prezentacji Apache OpenEJB podczas GeeCON 2009 postanowiłem ponownie wrócić do "deweloperki" przy nim i rozpocząłem boje z niedziałającymi testami jednostkowymi. Na moje (nie)szczęście na pierwszy ogień poszły przykłady związane z obsługą JAX-WS. Dwa przykłady w OpenEJB - webservices-security oraz webservices-ws-security kończyły się niejasnymi dla mnie komunikatami błędów. Jednym z nich był:
 -------------------------------------------------------------------------------
Test set: org.superbiz.calculator.CalculatorTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 2.703 sec <<< FAILURE!
testCalculatorViaWsInterface(org.superbiz.calculator.CalculatorTest) Time elapsed: 2.656 sec <<< ERROR!
javax.xml.ws.WebServiceException:
Could not find service named CalculatorWsPort in wsdl http://127.0.0.1:4204/CalculatorImpl?wsdl
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:155)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:143)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:55)
at javax.xml.ws.Service.<init>(Service.java:56)
at javax.xml.ws.Service.create(Service.java:680)
at org.superbiz.calculator.CalculatorTest.testCalculatorViaWsInterface(CalculatorTest.java:52)
...
Kompletnie nie miałem pojęcia, co z nim jest nie tak. Najpierw przyjrzałem się WSDL, ale nic nie mogłem namierzyć. Wszystko wydawało się w należytym porządku. Wpadłem na pomysł, aby zaprząc do pracy...Groovy. Tak na prawdę chciałem przygotować przykład, który wypisze mi wszystkie zdefiniowane usługi.
 jlaskowski@work /cygdrive/c/oss/openejb3/examples/webservice-security
$ groovysh
Groovy Shell (1.6.2, JVM: 1.6.0_13)
Type 'help' or '\h' for help.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
groovy:000> import javax.xml.ws.Service;
===> [import javax.xml.ws.Service;]
groovy:000> import javax.xml.namespace.QName;
===> [import javax.xml.ws.Service;, import javax.xml.namespace.QName;]
groovy:000> def calcService = Service.create(new URL("http://127.0.0.1:4204/CalculatorImpl?wsdl"), new QName("CalculatorWsService"));
ERROR javax.xml.ws.WebServiceException: CalculatorWsService is not a valid service.
Valid services are: {http://superbiz.org/wsdl}CalculatorWsService
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init> (WSServiceDelegate.java:192)
at com.sun.xml.internal.ws.client.WSServiceDelegate.<init> (WSServiceDelegate.java:159)
at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate (ProviderImpl.java:83)
at groovysh_evaluate.run (groovysh_evaluate:4)
...
groovy:000> exit
I jak widać, wystarczyło wykonać 3 instrukcje w Groovy, aby otrzymać komunikat, który powiedział mi wszystko - zamiast "CalculatorWsService" powinienem używać "{http://superbiz.org/wsdl}CalculatorWsService", a dokładniej, zamiast new QName("CalculatorWsService") powinno być new QName("http://superbiz.org/wsdl", "CalculatorWsService"), czyli jakimś cudem test nie uwzględniał przestrzeni nazewniczej "http://superbiz.org/wsdl".

Faktycznie jednak, rozwiązanie przyniosła mi całkowicie przypadkowa zmiana dostawcy JAX-WS z dosyć leciwego Apache CXF 2.0.9, który używany jest jeszcze przez OpenEJB na tego od Suna - trwają prace nad aktualizacją CXF w OpenEJB, więc następne komunikaty powinny być bardziej jasne (chyba, że w CXF nic się w tym obszarze nie zmieniło). Po zmianie wywołania z QName, testy zaczęły działać. Dokładnie tego oczekuję od dobrze dobranego narzędzia do zdiagnozowania problemu i Groovy spisał się wyśmienicie (aczkolwiek to faktycznie nie on, a zmiana dostawcy JAX-WS API, ale nie mogłem się oprzeć, aby nie pochwalić Groovy tym razem :)).

Skoro dotykam usług sieciowym pewnie powinienem użyć jakiegoś specjalizowanego narzędzia do przeglądania dostępnych usług w WSDL. Co mogłoby to być? Propozycje?