Как запретить 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>