Как запретить JAX-WS-Maven-Plugin создавать избыточные / несовместимые заглушки?

Среда: Netbeans IDE 8.2, Glassfish 4.1.1 на хосте Linux.

Данная настройка очень проста. Проект состоит из 3 Maven проектов

  • библиотека (Java-приложение Maven), которая, помимо прочего, предоставляет некоторые пользовательские сложные типы данных (аннотированные POJO JAXB)
  • веб- служба(веб-приложение Maven), предоставляющая операции с некоторыми типами библиотек
  • клиент (веб-приложение Maven), который использует веб-сервис

И клиент, и служба зависят от данной библиотеки и, таким образом, знают типы данных, определенные в этой библиотеке. Клиент использует веб-сервис через опцию "Новый клиент веб-сервиса" в контекстном меню файла проекта.

Проблема состоит в том, что во время компиляции клиента JAX-WS-Maven-Plugin будет генерировать заглушки для предоставленных операций и типов данных, используемых веб-сервисом. Как часть этого он также дублирует типы данных JAXB, содержащиеся в библиотеке. Эти заглушки скрывают типы библиотек от клиента веб-службы и вызывают ошибки из-за несовместимости типов. Удаление созданных заглушек вручную и перекомпиляция проекта решит проблему. На практике этот обходной путь не является решением, поскольку он включает в себя большую работу по рефакторингу, которую необходимо будет повторять после каждого небольшого изменения в коде.

Мой вопрос: как я могу предотвратить это?

Вот упрощенный пример игрушки, а именно "каталог веб-сайта", чтобы проиллюстрировать проблему с некоторым рабочим кодом. Проект состоит из трех частей:

  • WebsiteCatalogLibrary (Java-приложение Maven) содержит один класс "Website"
  • WebsiteCatalogService (веб-приложение Maven) предоставляет методы для добавления и удаления веб-сайтов, а также для запроса списка всех зарегистрированных веб-сайтов.
  • WebsiteCatalogClient (веб-приложение Maven) использует сервис.

В этом сценарии будет создана избыточная заглушка для класса Website (см. Ниже), вызывающая проблемы совместимости типов:

incompatible types: test.example.websitecatalog.lib.Website cannot be converted to test.example.websitecatalog.service.Website

Удаление заглушки веб-сайта и исправление импорта других автоматически сгенерированных источников jaxws-wsimport решит проблему. Однако сайт-заглушка не должен генерироваться в первую очередь. В приведенном ниже определении схемы для типа "Веб-сайт" четко указано, что оно является частью пространства имен. http://test.example.websitecatalog.lib и что этот тип используется в контексте методов веб-сервиса addSite(веб-сайт), deleteSite(веб-сайт) и getSites(). Несмотря на это, JAX-WS-Maven-Plugin будет автоматически генерировать класс Website внутри пакета test.example.websitecatalog.service, Этот класс скрывает фактический класс test.example.websitecatalog.lib.Website, который предоставляется клиенту через его зависимость от WebsiteCatalogLibrary.

// Website.java
package test.example.websitecatalog.lib;

import java.net.URL;
import java.util.Random;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Website", namespace = "http://lib.websitecatalog.example.test")
public class Website {

    public Website(String name, URL url) {
        this();
        this.name = name;
        this.url = url;
    }

    public Website() {
        id = RND.nextLong();
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public URL getUrl() {
        return url;
    }

    public void setUrl(URL url) {
        this.url = url;
    }

    @Override
    public String toString() {
        return name + " (" + url.toString() + ")";
    }

    private long id;
    private String name;
    private URL url;
    @XmlTransient
    private static final Random RND = new Random();
}

// WebsiteCatalogService.java
package test.example.websitecatlog.service;

import java.util.HashSet;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import test.example.websitecatalog.lib.Website;

@WebService(serviceName = "WebsiteCatalogService")
public class WebsiteCatalogService {

    @WebMethod(operationName = "addSite")
    public synchronized void addSite(
        @WebParam(name = "site") 
        Website site) {
        SITES.add(site);
    }

    @WebMethod(operationName = "deleteSite")
    public synchronized void deleteSite(
        @WebParam(name = "site")
        Website site) {
        SITES.remove(site);
    }

    @WebMethod(operationName = "getSites")
    @WebResult(name="sites")
    public synchronized Website[] getSites() {
        Website[] sites = new Website[SITES.size()];
        SITES.toArray(sites);
        return sites;
    }

    private static final HashSet<Website> SITES = new HashSet<>();
}

//WebsiteCatalogClient.java
package test.example.websitecatalog.client;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import test.example.websitecatalog.lib.Website;
import test.example.websitecatalog.service.WebsiteCatalogService;
import test.example.websitecatalog.service.WebsiteCatalogService_Service;

public class Client {

    public static void main(String args[]) {
        WebsiteCatalogService_Service wcs = new WebsiteCatalogService_Service();
        WebsiteCatalogService wc = wcs.getPort(WebsiteCatalogService.class);

        try {
            wc.addSite(new Website("Stackru", new URL("https://stackru.com")));
            wc.addSite(new Website("Example Site", new URL("https://exmaple.test")));
        } catch (MalformedURLException ex) {
            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
        }

        List<Website> catalog = wc.getSites();
        System.out.println("Currently the following sites are registered:");
        for(Website ws : catalog) {
            System.out.println(ws);
        }

    }
}

Следующие файлы автоматически генерируются из приведенного выше кода Java, поэтому любые изменения, внесенные в эти файлы, не будут постоянными.

<!-- WebsiteCatalogService?wsdl -->
<?xml version="1.0"?>
<!-- Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.2-b608 (trunk-7979; 2015-01-21T12:50:19+0000) JAXWS-RI/2.2.11-b150120.1832 JAXWS-API/2.2.12 JAXB-RI/2.2.12-b141219.1637 JAXB-API/2.2.13-b141020.1521 svn-revision#unknown. -->
<definitions targetNamespace="http://service.websitecatlog.example.test/" name="WebsiteCatalogService">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://service.websitecatlog.example.test/" schemaLocation="http://localhost:8080/WebsiteCatalogService/WebsiteCatalogService?xsd=1"/>
    </xsd:schema>
    <xsd:schema>
      <xsd:import namespace="http://lib.websitecatalog.example.test" schemaLocation="http://localhost:8080/WebsiteCatalogService/WebsiteCatalogService?xsd=2"/>
    </xsd:schema>
  </types>
  <message name="addSite">
    <part name="parameters" element="tns:addSite"/>
  </message>
  <message name="addSiteResponse">
    <part name="parameters" element="tns:addSiteResponse"/>
  </message>
  <message name="deleteSite">
    <part name="parameters" element="tns:deleteSite"/>
  </message>
  <message name="deleteSiteResponse">
    <part name="parameters" element="tns:deleteSiteResponse"/>
  </message>
  <message name="getSites">
    <part name="parameters" element="tns:getSites"/>
  </message>
  <message name="getSitesResponse">
    <part name="parameters" element="tns:getSitesResponse"/>
  </message>
  <portType name="WebsiteCatalogService">
    <operation name="addSite">
      <input wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/addSiteRequest" message="tns:addSite"/>
      <output wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/addSiteResponse" message="tns:addSiteResponse"/>
    </operation>
    <operation name="deleteSite">
      <input wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/deleteSiteRequest" message="tns:deleteSite"/>
      <output wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/deleteSiteResponse" message="tns:deleteSiteResponse"/>
    </operation>
    <operation name="getSites">
      <input wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/getSitesRequest" message="tns:getSites"/>
      <output wsam:Action="http://service.websitecatlog.example.test/WebsiteCatalogService/getSitesResponse" message="tns:getSitesResponse"/>
    </operation>
  </portType>
  <binding name="WebsiteCatalogServicePortBinding" type="tns:WebsiteCatalogService">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="addSite">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="deleteSite">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
    <operation name="getSites">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="WebsiteCatalogService">
    <port name="WebsiteCatalogServicePort" binding="tns:WebsiteCatalogServicePortBinding">
      <soap:address location="http://localhost:8080/WebsiteCatalogService/WebsiteCatalogService"/>
    </port>
  </service>
</definitions>

<!-- WebsiteCatalogService?xsd=1 -->
<?xml version="1.0"?>
<!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.2-b608 (trunk-7979; 2015-01-21T12:50:19+0000) JAXWS-RI/2.2.11-b150120.1832 JAXWS-API/2.2.12 JAXB-RI/2.2.12-b141219.1637 JAXB-API/2.2.13-b141020.1521 svn-revision#unknown. -->
<xs:schema version="1.0" targetNamespace="http://service.websitecatlog.example.test/">
  <xs:import namespace="http://lib.websitecatalog.example.test" schemaLocation="http://localhost:8080/WebsiteCatalogService/WebsiteCatalogService?xsd=2"/>
  <xs:element name="addSite" type="tns:addSite"/>
  <xs:element name="addSiteResponse" type="tns:addSiteResponse"/>
  <xs:element name="deleteSite" type="tns:deleteSite"/>
  <xs:element name="deleteSiteResponse" type="tns:deleteSiteResponse"/>
  <xs:element name="getSites" type="tns:getSites"/>
  <xs:element name="getSitesResponse" type="tns:getSitesResponse"/>
  <xs:complexType name="getSites">
    <xs:sequence/>
  </xs:complexType>
  <xs:complexType name="getSitesResponse">
    <xs:sequence>
      <xs:element name="sites" type="ns1:Website" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="addSite">
    <xs:sequence>
      <xs:element name="site" type="ns1:Website" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="addSiteResponse">
    <xs:sequence/>
  </xs:complexType>
  <xs:complexType name="deleteSite">
    <xs:sequence>
      <xs:element name="site" type="ns1:Website" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="deleteSiteResponse">
    <xs:sequence/>
  </xs:complexType>
</xs:schema>

<!-- WebsiteCatalogService?xsd=1 -->
<?xml version="1.0"?>
<!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is Metro/2.3.2-b608 (trunk-7979; 2015-01-21T12:50:19+0000) JAXWS-RI/2.2.11-b150120.1832 JAXWS-API/2.2.12 JAXB-RI/2.2.12-b141219.1637 JAXB-API/2.2.13-b141020.1521 svn-revision#unknown. -->
<xs:schema version="1.0" targetNamespace="http://lib.websitecatalog.example.test">
  <xs:complexType name="Website">
    <xs:sequence>
      <xs:element name="id" type="xs:long"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
      <xs:element name="url" type="xs:anyURI" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

0 ответов

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