Creazione e utilizzo dei servizi web nello stesso progetto Maven
Domanda
Sto cercando di costruire un progetto Maven, un pacchetto OSGI, che contiene servizi web. Sto usando Jax-WS con tutto il @WebService
Annotazioni per specificare i servizi Web che ho. Per caricare questi servizi web in una posizione del client che stai normalmente utilizzando wsgen
e wsimport
per l'esportazione/importazione di file WSDL. Ho intenzione di usare il Jaxws-Maven-Plugin Per farlo, ma ecco il problema:
Il pacchetto può fungere da server e client contemporaneamente. Può registrarsi come client a un nodo genitore dello stesso pacchetto (in esecuzione su un diverso JVM/host). Quindi questo progetto/bundle Maven definisce un'interfaccia per WebService e definisce una classe di implementazione che implementa questa interfaccia. Sia l'interfaccia che la classe usano il @WebService
annotazione come al solito.
@WebService
public interface Example {
public void callMe();
}
@WebService
public class ExampleImpl implements Example {
public void callMe() {};
}
E poi da qualche parte nel mio codice:
Endpoint p = Endpoint.publish(
"http://localhost:8080/example",
new ExampleImpl());
Il jaxws: goal wsgen Legge le annotazioni e crea i file di output (file .class, file .java, file WSDL, a seconda della configurazione ...). Ma come uso questi file durante il Jaxws: Wsimport Obiettivo per lo stesso mvn package
correre? Nello stesso progetto Maven voglio usare questo servizio web, quindi devo scrivere qualcosa del genere:
ExampleImplService service = new ExampleImplService();
Example port = service.getExampleImplPort();
port.callMe();
Il jaxws:gen
L'obiettivo è correre nel process-classes
fase in quanto deve leggere le classi compilate, ma jaxws:import
deve essere eseguito in generate-sources
fase per preparare tutto per la compilazione. E ora corro un problema con uova di pollo. Ho bisogno delle classi compilate per generare i file di output tramite wsgen
, ma ho bisogno dei file di output di wsgen
per wsimport
nel generate-sources
Fase di Maven. Il mio primo tentativo è stato quello di assegnare il jaxws:wsgen
obiettivo al generate-sources
Fase, ma ovviamente non funziona poiché le classi mancano/non sono ancora compilate.
Quali sono le mie opzioni per risolvere questo problema? Dovrei eseguire un antrun
Obiettivo da compilare alcuni classi (vale a dire solo le classi con il @WebService
annotazioni) prima del generate-sources
fase così jaxws:wsgen
può usarlo (in quella fase), creare i file di output che vengono quindi utilizzati da jaxws:wsimport
nel generate-sources
fase? Ci sono altri modi per risolvere questo problema di uova di pollo? Esistono altri "modi Maven" per la compilazione del server e del client parte dei servizi Web nello stesso progetto Maven? Dovrebbe btw. correre da un pulito mvn clean
Costruisci, quindi non voglio/mi piacciono le soluzioni come "Run mvn package
Due volte per generare prima i file WebServices e poi compilare tutto il resto ". In altre parole: mvn clean package
dovrebbe compilare l'intero pacchetto Maven Project/OSGI.
Soluzione
Sono riuscito a risolvere questo problema spostando il jaxsw:wsgen
obiettivo al generate-sources
fase. Uso i seguenti passaggi.
- Per prima cosa compilo le lezioni con
@WebService
Annotazioni tramite unantrun
esecuzione, che usano<javac>
per compilare le classi. Salvo i file .class risultanti in una directory temporanea che viene eliminata dopo aver creato gli stub client. - Creo il file WSDL dai file .class compilati con il
jaxws:wsgen
obiettivo. - Dalla directory temporanea creo i stub client con il normale
jaxws:wsimport
obiettivo. - Elimino la directory temporanea con un secondo
antrun
esecuzione.
Il file POM.xml risultante sembra segue (solo le parti pertinenti)
<properties>
<tmpdirectory>${java.io.tmpdir}${file.separator}${user.name}-${project.groupId}-${project.artifactId}</tmpdirectory>
</properties>
...
<plugin>
<!-- clean tmp directory at every "mvn clean" -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<filesets>
<fileset>
<directory>${tmpdirectory}</directory>
</fileset>
</filesets>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.6.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
<executions>
<execution>
<!-- compile webservice classes into tmp directory -->
<id>mini compile of webservices</id>
<phase>generate-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<property name="compile_classpath" refid="maven.compile.classpath"/>
<mkdir dir="${tmpdirectory}" />
<javac includeAntRuntime="false"
classpath="${compile_classpath}"
destdir="${tmpdirectory}">
<src path="${project.build.sourceDirectory}" />
<include name="org/example/project/*/webservice/*.java" />
</javac>
</target>
</configuration>
</execution>
<execution>
<!-- delete temporary directory (in case mvn clean is not called) -->
<id>clean up tmp dir</id>
<phase>process-sources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<delete dir="${tmpdirectory}" />
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.10</version>
<executions>
<execution>
<!-- generate WSDL file from the compiled classes in tmp directory -->
<id>generate wsdl file</id>
<phase>generate-sources</phase>
<goals>
<goal>wsgen</goal>
</goals>
<configuration>
<sei><!-- service endpoint implementation --></sei>
<destDir>${tmpdirectory}</destDir>
<genWsdl>true</genWsdl>
<resourceDestDir>${tmpdirectory}</resourceDestDir>
</configuration>
</execution>
<execution>
<!-- create client stub files -->
<id>create client files from wsdl file</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<keep>true</keep>
<wsdlDirectory>${tmpdirectory}</wsdlDirectory>
</configuration>
</execution>
</executions>
</plugin>
Altri suggerimenti
Dove definisci il plug -in dovrai impostare due esecuzioni separate, una per WSGEN e l'altra WSIMport.
...il tempo passa...
Usa Maven per attivare un WSGen & Wsimport di fila, usando WSDLOLOCATION