Создание и использование веб-сервисов в одном проекте Maven

Я пытаюсь создать проект maven, пакет OSGi, который содержит веб-сервисы. Я использую JAX-WS со всеми @WebService аннотации для указания веб-сервисов у меня есть. Чтобы загрузить эти веб-сервисы в расположении клиента, которое вы обычно используете wsgen а также wsimport для экспорта / импорта файлов WSDL. Я планирую использовать jaxws-maven-plugin для этого, но вот проблема:

Пакет может выступать в роли сервера и клиента одновременно. Он может зарегистрироваться как клиент для родительского узла того же пакета (работающего на другой JVM/ хосте). Таким образом, этот проект / пакет maven определяет интерфейс для веб-сервиса и определяет класс реализации, который реализует этот интерфейс. И интерфейс, и класс используют @WebService аннотация как обычно.

@WebService
public interface Example {
    public void callMe();
}

@WebService
public class ExampleImpl implements Example {
    public void callMe() {};
}

И тогда где-то в моем коде:

Endpoint p = Endpoint.publish(
                 "http://localhost:8080/example",
                 new ExampleImpl());    

Цель jaxws: wsgen читает аннотации и создает выходные файлы (файлы.class, файлы.java, файлы WSDL, в зависимости от конфигурации...). Но как мне использовать эти файлы во время цели jaxws:wsimport для того же mvn package бежать? В том же проекте Maven я хочу использовать этот веб-сервис, поэтому мне нужно написать что-то вроде этого:

ExampleImplService service = new ExampleImplService();
Example port = service.getExampleImplPort();
port.callMe();

jaxws:gen цель работает в process-classes фаза, поскольку она должна читать скомпилированные классы, но jaxws:import должен быть запущен в generate-sources фаза, чтобы подготовить все для компиляции. И теперь я столкнулся с проблемой куриного яйца. Мне нужны скомпилированные классы для генерации выходных файлов через wsgen, но мне нужны выходные файлы wsgen за wsimport в generate-sources фаза мавена. Моей первой попыткой было назначить jaxws:wsgen цель к generate-sources фаза, но, конечно, она не работает, так как классы отсутствуют / еще не скомпилированы.

Какие у меня есть варианты решения этой проблемы? Должен ли я запустить antrun цель скомпилировать некоторые классы (а именно только классы с @WebService аннотации) до generate-sources фаза так jaxws:wsgen может использовать его (на этом этапе), создать выходные файлы, которые затем используются jaxws:wsimport в generate-sources фаза? Есть ли другие способы решить эту проблему куриного яйца? Существуют ли другие "maven-способы" для компиляции серверной и клиентской части веб-сервисов в одном проекте maven? Это должно быть кстати. бежать из чистого mvn clean строить, поэтому я не хочу / не нравится никаких решений, таких как "запустить mvn package дважды, чтобы сначала сгенерировать файлы веб-сервисов, а затем скомпилировать все остальное ". Другими словами: mvn clean package должен скомпилировать весь проект maven / osgi.

2 ответа

Решение

Мне удалось решить эту проблему, переместив jaxsw:wsgen цель к generate-sources фаза. Я использую следующие шаги.

  1. Сначала я собираю классы с @WebService аннотации через antrun исполнение, которое используют <javac> составить классы. Я сохраняю полученные файлы.class во временном каталоге, который удаляется после создания клиентских заглушек.
  2. Я создаю файл WSDL из скомпилированных файлов.class с jaxws:wsgen Цель.
  3. Из временного каталога я создаю клиентские заглушки с обычным jaxws:wsimport Цель.
  4. Я удаляю временную директорию со вторым antrun выполнение.

Полученный файл pom.xml выглядит следующим образом (только соответствующие части)

<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>

Где вы определяете свой плагин, вам нужно будет настроить два отдельных исполнения: одно для wsgen, а другое для wsimport.

...Время проходит...

Используйте Maven для запуска wsgen & wsimport подряд, используя wsdlLocation

Другие вопросы по тегам