SCAlanie z JAX-WS
Z Jacek Laskowski - Wiki Projektanta Java EE
Ostatnie dwa artykuły o SCA - SCAlenie (kompozyt) z Apache Tuscany i Apache Maven oraz SCA z językami skryptowymi w wykonaniu Apache Tuscany, Jetty i Maven 2 - dotyczyły łączenia usług, które działały w ramach pojedyńczej wirtualnej maszyny Java (JVM). Rozproszenie usług było pozorne i często spotykałem się z uwagami, że nie prezentują niczego nowatorskiego, czego nie możnaby osiągnąć korzystając z tradycyjnych metod integracji. Artykuły skupiały się raczej na prostocie tworzenia usług korzystając z SCA oraz języków skryptowych niż na prostocie integracji usług rozproszonych.
W tym artykule wyjdziemy poza ramy pojedyńczej wirtualnej maszyny i faktycznie dotkniemy kwestii integracji usług rozproszonych. Zestawimy środowisko z dwoma serwerami aplikacyjnymi Jetty oraz GlassFish, w którym uruchomimy SCAlenie na jednym serwerze, składające się z usługi PolishEnglishDictionaryService będącej usługą sieciową (ang. web service) uruchomioną na drugim. Istotą artykułu będzie zaprezentowanie deklaratywnego konstruowania SCAlenia poprzez definiowanie elementów składowych w deskryptorze XML. Cel osiągniemy korzystając również z artykułu Tworzenie usługi sieciowej z JAX-WS. Na ich podstawie utworzone zostanie SCAlenie z wykorzystaniem mechanizmu składania usług rozproszonych opartych o JAX-WS w celu udostępnienia kolejnej, bardziej specjalizowanej funkcjonalności.
Wersje oprogramowania w środowisku uruchomieniowym:
- Apache Tuscany 1.0.0-SNAPSHOT
- GlassFish v2 b50f
- Jetty 6.1.3
- Apache Maven 2.0.7
- (opcjonalnie) Eclipse IDE 3.3RC4
Zakłada się, że powyższe oprogramowanie jest zainstalowane i działa poprawnie. Instalacja oprogramowania sprowadza się do pobrania i rozpakowania paczek w wybranym katalogu.
Kompletny projekt jest dostępny jako sca-dictionary-jaxws.zip.
Spis treści |
Utworzenie projektu aplikacji internetowej - sca-dictionary-jaxws
W poprzednich artykułach korzystaliśmy z pomocy Apache Maven 2 (m2) do tworzenia struktury projektu aplikacji. Tym razem skorzystamy z już istniejącego projektu, który był stworzony w artykule SCA z językami skryptowymi w wykonaniu Apache Tuscany, Jetty i Maven 2 i zmodyfikujemy go odpowiednio. Tym samym artykuł będzie kontynuacją poprzedniego, przez co zostanie zademonstrowany jeszcze jeden aspekt tworzenia aplikacji - stopniowy rozwój przez dodawanie bardziej specjalizowanych funkcjonalności.
Pobieramy projekt aplikacji stworzony w artykule SCA z językami skryptowymi w wykonaniu Apache Tuscany, Jetty i Maven 2 - sca-dictionary-web.zip. Paczkę rozpakowujemy do wybranego przez siebie katalogu, np. C:\.
Zmieniamy nazwę projektu na sca-dictionary-jaxws.
$ mv sca-dictionary-web sca-dictionary-jaxws
Przechodzimy do katalogu sca-dictionary-jaxws.
$ cd sca-dictionary-jaxws
Kolejne polecenia wydawane będą właśnie z tego katalogu, który reprezentuje nasz projekt SCAlenia w aplikacji internetowej.
Import projektu do zintegrowanego środowiska programistycznego - Eclipse IDE (opcjonalnie)
Wykonujemy polecenie mvn eclipse:eclipse, aby utworzyć pliku projektu do importu projektu do Eclipse IDE. W zależności od wybranego graficznego środowiska programistycznego (IDE) polecenie może nieznacznie się różnić. W przypadku NetBeans IDE 6.0M9 nie jest w ogóle konieczne, gdyż NetBeans IDE wspiera projekty zarządzane przez m2.
$ mvn eclipse:eclipse [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'eclipse'. [INFO] ---------------------------------------------------------------------------- [INFO] Building SCAlenie Dictionary w Aplikacji Internetowej [INFO] task-segment: [eclipse:eclipse] [INFO] ---------------------------------------------------------------------------- ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4 seconds [INFO] Finished at: Tue Jun 26 20:05:14 CEST 2007 [INFO] Final Memory: 6M/254M [INFO] ------------------------------------------------------------------------
Komunikat BUILD SUCCESSFUL wskazuje na poprawnie wykonane polecenie. Uruchamiamy Eclipse IDE i importujemy projekt (File > Import > General > Existing Projects into Workspace).
UWAGA: Może się zdarzyć, że po imporcie pojawią się komunikaty błędu - Unbound classpath variable: 'M2_REPO/junit/junit/4.2/junit-4.2.jar' in project sca-dictionary-jaxws - co oznacza brak definicji zmiennej M2_REPO w wybranej przestrzeni roboczej. Naprawiamy błąd poprzez Window > Preferences... > Java > Build Path > Classpath Variables > New.... Dodajemy M2_REPO ze wskazaniem na lokalne repozytorium M2, potwierdzamy ponowne przebudowanie projektu i voila - projekt jest czysty, bez jakichkolwiek komunikatów ostrzegawczych, gotowy do dalszego rozwoju.
Modyfikacja konfiguracji projektu - pom.xml
Głównym elementem projektu zarządzanego przez m2 jest deskryptor projektu - pom.xml - znajdujący się w katalogu głównym projektu. W nim definiujemy zależnosci projektowe. Jedną z zależności są biblioteki, z których będzie korzystał projekt.
Na potrzeby tego artykułu konieczne będzie dodanie biblioteki udostępniającej możliwość budowania SCAlenia przy pomocy zdalnych usług sieciowych - tuscany-binding-ws-axis2.
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-ws-axis2</artifactId>
<version>${tuscany.version}</version>
<scope>runtime</scope>
</dependency>
Uruchamiając 2 serwery jednocześnie, co będzie miało miejsce w naszym artykule, konieczne będzie zagwarantowanie, że żaden z serwerów nie współdzieli tego samego portu. Dodajemy do pom.xml możliwość uruchomienia Jetty na porcie innym niż domyślny - 8080, który jest również domyślnym portem dla Glassfish.
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.3</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>${jetty.port}</port>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
Wywołanie mvn z parametrem jetty.port będzie równoznaczne z uruchomieniem Jetty na podanym porcie.
Ostatecznie plik pom.xml powinien wyglądać następujaco:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pl.jaceklaskowski.sca.dictionary</groupId>
<artifactId>sca-dictionary-jaxws</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>SCAlenie Dictionary w Aplikacji Internetowej</name>
<url>http://www.JacekLaskowski.pl</url>
<properties>
<jetty.port>8080</jetty.port>
<tuscany.version>1.0-incubating-SNAPSHOT</tuscany.version>
</properties>
<build>
<finalName>${artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.3</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>${jetty.port}</port>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>apache.snapshot</id>
<url>http://people.apache.org/repo/m2-snapshot-repository</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-host-webapp</artifactId>
<version>${tuscany.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-implementation-java-runtime</artifactId>
<version>${tuscany.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-implementation-script</artifactId>
<version>${tuscany.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-ws-axis2</artifactId>
<version>${tuscany.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Na koniec weryfikujemy poprawną konfigurację projektu przez wydanie polecenia mvn clean jetty:run-exploded -Djetty.port=9090, które uruchomi poprzednio stworzoną aplikację w środowisku Jetty nasłuchującego na porcie 9090. W tak skonfigurowanym projekcie, adres aplikacji będzie http://localhost:9090/sca-dictionary-jaxws/ (w stosunku do macierzystego projektu, który zmodyfikowaliśmy, zmieniła się nazwa projektu, a więc i kontekst aplikacji oraz port, na którym nasłuchuje serwer).
$ mvn clean jetty:run-exploded -Djetty.port=9090 [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'jetty'. [INFO] ---------------------------------------------------------------------------- [INFO] Building SCAlenie Dictionary w Aplikacji Internetowej [INFO] task-segment: [clean, jetty:run-exploded] [INFO] ---------------------------------------------------------------------------- ... [INFO] [jetty:run-exploded] [INFO] Configuring Jetty for project: SCAlenie Dictionary w Aplikacji Internetowej 2007-06-26 20:12:39.093::INFO: Logging to STDERR via org.mortbay.log.StdErrLog [INFO] Context path = /sca-dictionary-jaxws [INFO] Tmp directory = c:\sca-dictionary-jaxws\target\work [INFO] Web defaults = jetty default [INFO] Web overrides = none [INFO] Starting jetty 6.1.3 ... 2007-06-26 20:12:39.187::INFO: jetty-6.1.3 2007-06-26 20:12:39.359::INFO: No Transaction manager found - if your webapp requires one, please configure one. 2007-06-26 20:12:40.843::INFO: Started SelectChannelConnector @ 0.0.0.0:9090 [INFO] Started Jetty Server
Zatrzymujemy serwer kombinacją klawiszy Ctrl-C.
2007-06-26 20:15:54.531::INFO: Shutdown hook executing [INFO] 2007-06-26 20:15:54.640::INFO: Shutdown hook completeJetty server exiting. [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3 minutes 30 seconds [INFO] Finished at: Tue Jun 26 20:15:54 CEST 2007 [INFO] Final Memory: 13M/254M [INFO] ------------------------------------------------------------------------
Utworzenie usługi PolishEnglishDictionaryService z JAX-WS
W projekcie macierzystym, usługa PolishEnglishDictionaryService była napisana w Javie i jej integracja ze SCAleniem odbywała się poprzez mechanizmy języka. Tym razem, usługa jest zdalną usługą sieciową, która jest niedostępna lokalnie. Komunikacja z usługą sieciową będzie zlecona środowisku SCA - Apache Tuscany.
Rozpoczynamy od usunięcia implementacji usługi - klasy PolishEnglishDictionaryServiceImpl, gdyż wywołanie usługi sprowadza się do zdalnego wywołania usługi sieciowej PolishEnglishDictionaryService opisanej przez WSDL. Usuwamy plik PolishEnglishDictionaryServiceImpl.java z katalogu src/main/java/pl/jaceklaskowski/sca/dictionary. Nie jest to konieczny krok, jednakże porządkuje projekt.
Modyfikacja interfejsu usługi PolishEnglishDictionaryService
W projekcie macierzystym usługa PolishEnglishDictionaryService była zbudowana przy pomocy konstrukcji języka Java - interfejs oraz klasa będąca implementacją interfejsu. Żadna z konstrukcji nie była specyficzna dla SCA. Tym razem konieczne będzie określenie roli interfejsu przy konstrukcji SCAlenia tak, aby traktowany był on jako część integracji usługi zdalnej. Skorzystamy z adnotacji @Remotable oraz @Service w interfejsie PolishEnglishDictionaryService.
Plik PolishEnglishDictionaryService.java w katalogu src/main/java/pl/jaceklaskowski/sca/dictionary powinien wyglądać następująco:
package pl.jaceklaskowski.sca.dictionary;
import org.osoa.sca.annotations.Remotable;
import org.osoa.sca.annotations.Service;
@Remotable
@Service
public interface PolishEnglishDictionaryService {
String translate(String word);
}
Deskryptor SCAlenia - Dictionary.composite
Modyfikujemy deskryptor SCAlenia - Dictionary.composite - o nową definicję usługi PolishEnglishDictionaryService, która jest usługą sieciową opisaną przez plik WSDL.
<reference name="PolishEnglishDictionaryServiceComponent" promote="DictionaryServiceComponent/polishEnglishDictionaryService">
<interface.java interface="pl.jaceklaskowski.sca.dictionary.PolishEnglishDictionaryService" />
<binding.ws
wsdlElement="http://dictionary.jaxws.jaceklaskowski.pl/#wsdl.port(PolishEnglishDictionaryService/PolishEnglishDictionaryPort)" />
</reference>
Jak można zauważyć, w tym przykładzie korzystamy z elementu reference zamiast component do definicji zależności. Wykorzystanie elementów reference oraz component może być traktowane zamiennie i jedynie ich położenie nakłada obowiązek korzystania z pewnych atrybutów, które określają ich przynależność w konfiguracji SCAlenia. Porównanie definicji zależności SCAlenia za pomocą reference oraz component pozostawiamy jako zadanie domowe.
Wykorzystanie elementu reference znosi konieczność korzystania z elementu reference do definicji zależności od PolishEnglishDictionaryServiceComponent w ramach definicji komponentu DictionaryServiceComponent, więc go usuwamy.
<component name="DictionaryServiceComponent"> <implementation.java class="pl.jaceklaskowski.sca.dictionary.DictionaryServiceImpl" /> <reference name="englishPolishDictionaryService" target="EnglishPolishDictionaryServiceComponent" /> <reference name="germanPolishDictionaryService" target="GermanPolishDictionaryServiceComponent" /> </component>
Ostatecznie deskryptor SCAlenia powinien wyglądać następująco:
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="Dictionary">
<component name="DictionaryServiceComponent">
<implementation.java class="pl.jaceklaskowski.sca.dictionary.DictionaryServiceImpl" />
<reference name="englishPolishDictionaryService" target="EnglishPolishDictionaryServiceComponent" />
<reference name="germanPolishDictionaryService" target="GermanPolishDictionaryServiceComponent" />
</component>
<reference name="PolishEnglishDictionaryServiceComponent" promote="DictionaryServiceComponent/polishEnglishDictionaryService">
<interface.java interface="pl.jaceklaskowski.sca.dictionary.PolishEnglishDictionaryService" />
<binding.ws
wsdlElement="http://dictionary.jaxws.jaceklaskowski.pl/#wsdl.port(PolishEnglishDictionaryService/PolishEnglishDictionaryPort)" />
</reference>
<component name="EnglishPolishDictionaryServiceComponent">
<implementation.java class="pl.jaceklaskowski.sca.dictionary.EnglishPolishDictionaryServiceImpl" />
</component>
<component name="GermanPolishDictionaryServiceComponent">
<implementation.script script="pl/jaceklaskowski/sca/dictionary/groovy/GermanPolishDictionaryServiceImpl.groovy"/>
</component>
</composite>
Plik Dictionary.composite znajduje się w katalogu src/main/resources.
Uruchomienie SCAlenia
Uruchomienie usługi sieciowej
Rozpoczynamy od uruchomienia usługi sieciowej PolishEnglishDictionaryService, która jest zarządzana przez serwer aplikacyjny Glassfish (zakłada się tym samym, że usługa została już zainstalowana na serwerze - kroki uruchomieniowe opisane są w artykule Tworzenie usługi sieciowej z JAX-WS).
W zależności od konfiguracji serwera będziemy zmuszeni do przejścia do katalogu domowego serwera GlassFish lub po prostu wykonania polecenia asadmin.bat z parametrami, jeśli katalog skryptów jest w zmiennej PATH.
$ asadmin.bat start-domain domain1 Starting Domain domain1, please wait. Log redirected to c:\apps\glassfish\domains\domain1\logs\server.log. Redirecting output to C:/apps/glassfish/domains/domain1/logs/server.log Domain domain1 is ready to receive client requests. Additional services are being started in background. Domain [domain1] is running [Sun Java System Application Server 9.1 (build b50f-beta3)] with its configuration and logs at: [c:\apps\glassfish\domains]. Admin Console is available at [http://localhost:4848]. Use the same port [4848] for "asadmin" commands. User web applications are available at these URLs: [http://localhost:8080 https://localhost:8181 ]. Following web-contexts are available: [/web1 /__wstx-services ]. Standard JMX Clients (like JConsole) can connect to JMXServiceURL: [service:jmx:rmi:///jndi/rmi://dev:8686/jmxrmi] for domain management purposes. Domain listens on at least following ports for connections: [8080 8181 4848 3700 3820 3920 8686 ]. Domain does not support application server clusters and other standalone instances.
Pobranie deskryptora usługi sieciowej - WSDL
Niezbędnym elementem konstruowania SCAlenia korzystającego z usługi zdalnej jest pobranie pliku WSDL. Za pomocą WSDL środowisko uruchomieniowe rozpozna sposób komunikacji z usługą.
Otwieramy konsolę GlassFish dostępną pod adresem http://localhost:4848. Wybieramy węzeł Web Services, gdzie wybieramy węzeł PolishEnglishDictionary.
Pobieramy plik WSDL, który dostępny jest w menu View WSDL i zapisujemy w podkatalogu projektu - src/main/resources/wsdl jako PolishEnglishDictionaryService.wsdl (nazwa pliku nie ma znaczenia dla Apache Tuscany, a jedynie rozszerzenie .wsdl).
Uruchomienie aplikacji internetowej
Uruchomienie aplikacji internetowej, której częścią jest SCAlenie, które z kolei korzysta z usługi zdalnej, sprowadza się do uruchomienia serwera Jetty za pomocą m2.
$ mvn clean jetty:run-exploded -Djetty.port=9090 [INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'jetty'. [INFO] ---------------------------------------------------------------------------- [INFO] Building SCAlenie Dictionary w Aplikacji Internetowej [INFO] task-segment: [clean, jetty:run-exploded] [INFO] ---------------------------------------------------------------------------- ... [INFO] [jetty:run-exploded] [INFO] Configuring Jetty for project: SCAlenie Dictionary w Aplikacji Internetowej 2007-06-26 20:40:54.593::INFO: Logging to STDERR via org.mortbay.log.StdErrLog [INFO] Context path = /sca-dictionary-jaxws [INFO] Tmp directory = c:\sca-dictionary-jaxws\target\work [INFO] Web defaults = jetty default [INFO] Web overrides = none [INFO] Starting jetty 6.1.3 ... 2007-06-26 20:40:54.687::INFO: jetty-6.1.3 2007-06-26 20:40:55.375::INFO: No Transaction manager found - if your webapp requires one, please configure one. log4j:WARN No appenders could be found for logger (org.apache.axiom.om.util.StAXUtils). log4j:WARN Please initialize the log4j system properly. 2007-06-26 20:40:57.375::INFO: Started SelectChannelConnector @ 0.0.0.0:9090 [INFO] Started Jetty Server
Otwieramy przeglądarkę i wskazujemy na adres http://localhost:9090/sca-dictionary-jaxws/.
Uruchomienie strony startowej aplikacji internetowej uruchomiło SCAlenie, które z kolei wywołało usługę zdalną uruchomioną na serwerze GlassFish. Jedyny krok związany z faktycznym programowaniem był związany z określeniem interfejsu usługi. Dostarczenie implementacji przekazaliśmy do Tuscany.
Zamknięcie serwera Jetty to wciśnięcie kombinacji klawiszy Ctrl-C, podczas gdy zatrzymanie GlassFisha to wywołanie polecenie asadmin z parametrami stop-domain domain1 (ponownie prostota wykonania polecenia zależy od konfiguracji środowiska).
Dobrym przykładem na weryfikację poprawnej integracji SCAlenia z usługą sieciową jest wyłączenie serwera GlassFish. Kiedy usługa sieciowa nie jest dostępna, innymi słowy, kiedy serwer GlassFish, na którym pracuje usługa, nie jest uruchomiony, pojawi się poniższy wyjątek.
2007-06-26 20:45:13.265:/sca-dictionary-jaxws:WARN: exception initializing SCADomain
org.osoa.sca.ServiceRuntimeException: org.apache.tuscany.sca.contribution.service.ContributionRuntimeException: java.net.ConnectException: Connection refused: connect
at org.apache.tuscany.sca.host.embedded.SCADomain.createNewInstance(SCADomain.java:263)
at org.apache.tuscany.sca.host.embedded.SCADomain.newInstance(SCADomain.java:81)
at org.apache.tuscany.sca.webapp.SCADomainHelper.initSCADomain(SCADomainHelper.java:63)
at org.apache.tuscany.sca.webapp.TuscanyContextListener.contextInitialized(TuscanyContextListener.java:37)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1218)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
at org.mortbay.jetty.Server.doStart(Server.java:210)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:134)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:341)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:286)
at org.mortbay.jetty.plugin.Jetty6RunWarExploded.execute(Jetty6RunWarExploded.java:163)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:443)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:493)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:463)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:311)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:334)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:125)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:280)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.tuscany.sca.contribution.service.ContributionRuntimeException: java.net.ConnectException: Connection refused: connect
at org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLDocumentProcessor$WSDLLocatorImpl.getImportInputSource(WSDLDocumentProcessor.java:88)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseSchema(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseSchema(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseTypes(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.parseDefinitions(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLDocumentProcessor.read(WSDLDocumentProcessor.java:141)
at org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLDocumentProcessor.read(WSDLDocumentProcessor.java:52)
at org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor.read(ExtensibleURLArtifactProcessor.java:63)
at org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl.processReadPhase(ContributionServiceImpl.java:301)
at org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl.addContribution(ContributionServiceImpl.java:251)
at org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl.contribute(ContributionServiceImpl.java:119)
at org.apache.tuscany.sca.host.embedded.impl.DefaultSCADomain.<init>(DefaultSCADomain.java:104)
at org.apache.tuscany.sca.host.embedded.SCADomain.createNewInstance(SCADomain.java:229)
... 39 more
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.Socket.connect(Socket.java:519)
at java.net.Socket.connect(Socket.java:469)
at sun.net.NetworkClient.doConnect(NetworkClient.java:157)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:382)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:509)
at sun.net.www.http.HttpClient.<init>(HttpClient.java:231)
at sun.net.www.http.HttpClient.New(HttpClient.java:304)
at sun.net.www.http.HttpClient.New(HttpClient.java:316)
at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:817)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:769)
at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:694)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:938)
at java.net.URL.openStream(URL.java:1007)
at org.apache.tuscany.sca.interfacedef.wsdl.xml.WSDLDocumentProcessor$WSDLLocatorImpl.getImportInputSource(WSDLDocumentProcessor.java:86)
... 56 more
Brak pliku WSDL (plik z rozszerzeniem .wsdl), który definiuje zdalną usługę, wiąże się z poniższym komunikatem błędu.
2007-06-26 20:47:32.203:/sca-dictionary-jaxws:WARN: exception initializing SCADomain
org.osoa.sca.ServiceRuntimeException: org.osoa.sca.ServiceRuntimeException: org.apache.tuscany.sca.core.runtime.ActivationException: java.lang.NullPointerException
at org.apache.tuscany.sca.host.embedded.SCADomain.createNewInstance(SCADomain.java:263)
at org.apache.tuscany.sca.host.embedded.SCADomain.newInstance(SCADomain.java:81)
at org.apache.tuscany.sca.webapp.SCADomainHelper.initSCADomain(SCADomainHelper.java:63)
at org.apache.tuscany.sca.webapp.TuscanyContextListener.contextInitialized(TuscanyContextListener.java:37)
at org.mortbay.jetty.handler.ContextHandler.startContext(ContextHandler.java:530)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:135)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1218)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:500)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.jetty.handler.ContextHandlerCollection.doStart(ContextHandlerCollection.java:161)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerCollection.doStart(HandlerCollection.java:147)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:117)
at org.mortbay.jetty.Server.doStart(Server.java:210)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:40)
at org.mortbay.jetty.plugin.Jetty6PluginServer.start(Jetty6PluginServer.java:134)
at org.mortbay.jetty.plugin.AbstractJettyMojo.startJetty(AbstractJettyMojo.java:341)
at org.mortbay.jetty.plugin.AbstractJettyMojo.execute(AbstractJettyMojo.java:286)
at org.mortbay.jetty.plugin.Jetty6RunWarExploded.execute(Jetty6RunWarExploded.java:163)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo(DefaultPluginManager.java:443)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(DefaultLifecycleExecutor.java:539)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(DefaultLifecycleExecutor.java:493)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(DefaultLifecycleExecutor.java:463)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(DefaultLifecycleExecutor.java:311)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(DefaultLifecycleExecutor.java:278)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(DefaultLifecycleExecutor.java:143)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:334)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:125)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:280)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.osoa.sca.ServiceRuntimeException: org.apache.tuscany.sca.core.runtime.ActivationException: java.lang.NullPointerException
at org.apache.tuscany.sca.host.embedded.impl.DefaultSCADomain.<init>(DefaultSCADomain.java:148)
at org.apache.tuscany.sca.host.embedded.SCADomain.createNewInstance(SCADomain.java:229)
... 39 more
Caused by: org.apache.tuscany.sca.core.runtime.ActivationException: java.lang.NullPointerException
at org.apache.tuscany.sca.core.runtime.CompositeActivatorImpl.activate(CompositeActivatorImpl.java:602)
at org.apache.tuscany.sca.host.embedded.impl.DefaultSCADomain.<init>(DefaultSCADomain.java:145)
... 40 more
Caused by: java.lang.NullPointerException
at org.apache.tuscany.sca.binding.axis2.Axis2ReferenceBindingProvider.createServiceClient(Axis2ReferenceBindingProvider.java:128)
at org.apache.tuscany.sca.binding.axis2.Axis2ReferenceBindingProvider.initServiceClient(Axis2ReferenceBindingProvider.java:104)
at org.apache.tuscany.sca.binding.axis2.Axis2ReferenceBindingProvider.<init>(Axis2ReferenceBindingProvider.java:76)
at org.apache.tuscany.sca.binding.axis2.Axis2BindingProviderFactory.createReferenceBindingProvider(Axis2BindingProviderFactory.java:48)
at org.apache.tuscany.sca.binding.axis2.Axis2BindingProviderFactory.createReferenceBindingProvider(Axis2BindingProviderFactory.java:37)
at org.apache.tuscany.sca.core.runtime.CompositeActivatorImpl.configureComposite(CompositeActivatorImpl.java:129)
at org.apache.tuscany.sca.core.runtime.CompositeActivatorImpl.activate(CompositeActivatorImpl.java:599)
... 41 more
Na uwagę zasługuje prostota konstruowania SCAlenia przy pomocy różnych technologii. W poprzednich artykułach mieliśmy możliwość skorzystania z języka silnie-typowanego Java i języka skryptowego Groovy, a tym razem skorzystaliśmy z integracji opartej o usługę zdalną zbudowaną za pomocą JAX-WS. Jakby tego było mało - wciąż nie wyczerpaliśmy możliwości oferowanych nam przez specyfikację SCA w wykonaniu Apache Tuscany. Więcej informacji znajduje się na stronach Service Component Architecture Specifications. Polecam!

