Is it possible to migrate existing JAX-RPC web services to JAX-WS without any WSDL or domain model...












0















I am preparing to migrate SOAP web services from JAX-RPC to JAX-WS.
It has to be as smooth as possible:




  • WSDL must not be modified.

  • New JAX-WS web services should use the same implementation as their old JAX-RPC counterparts (maximum reuse of code, no copy/paste).

  • New JAX-WS web services should be able to operate in parallel with their old JAX-RPC counterparts.


How it is working today:




  • Existing WSDL are generated from the JAX-RPC @WebService classes,

  • XML schemas are hand-written, and compiled by XMLBeans.

  • At runtime, XMLBeans objects are converted into model objects by hand-written *Converter classes.


How we want to make it work after the migration:




  • New JAX-WS web services will be contract-first: Service Endpoint Interfaces (SEI) will be generated from existing WSDL.

  • XML types should be binded directly to existing model objects.

  • Binding configuration should be external (not use annotations).


I am using wsimport goal from jaxws-maven-plugin (http://www.mojohaus.org/jaxws-maven-plugin/) to generate Java code from WSDL.
The services will be deployed as a web app (not EJB) in WebLogic Server 12.2.1.3.



I tried without success to use:




  • JAX-WS and JAXB binding customizations


    • WLS doc says that "If customizations are required, Oracle recommends [creating external binding] to maintain flexibility by keeping the customizations separate from the WSDL or XML Schema document.")

    • it seems that I have to use annotations, and I couldn't find a way to use XmlAdapters without modifying model objects (to add XmlJavaTypeAdapter).



  • EclipseLink MOXy external binding (EclipseLink MOXy is the default data binding and JAXB provider in WLS12.2.1.3).


    • The doc states that "EclipseLink MOXy provides (...) the ability to use an external metadata file to configure the equivalent of JAXB annotations without modifying the Java source it refers to"

    • but says also that "EclipseLink MOXy extensions can be leveraged (...) only in the Java to WSDL scenario".

    • as a matter of fact I couldn't manage to have maven tooling nor the app to use this binding.




Put in code, it looks like:



pom.xml



<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<artifactId>myapp</artifactId>
<packaging>war</packaging>

<groupId>sandbox.jaxws_migration</groupId>
<version>1.0.0-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.5</version>
<dependencies>
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-tools</artifactId>
<version>2.3.1</version>
</dependency>
<!-- see https://java.net/jira/browse/WSIT-1672 -->
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-rt</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>


src/wsdl/hello_world.wsdl



<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="HelloWorld"
targetNamespace="http://service.myapp/helloworld/"
xmlns:tns ="http://service.myapp/helloworld/"
xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:p ="http://types.myapp/person/"
>

<wsdl:types>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://service.myapp/helloworld/">
<xs:import namespace="http://types.myapp/person/" schemaLocation="../xsd/person.xsd"/>
<xs:element name="sayHello">
<xs:complexType>
<xs:sequence>
<xs:element name="who" type="p:person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="sayHelloResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="greetings" type="xs:string">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>

<wsdl:message name="sayHello"> <wsdl:part name="p" element="tns:sayHello"/> </wsdl:message>
<wsdl:message name="sayHelloResponse"><wsdl:part name="p" element="tns:sayHelloResponse"/></wsdl:message>

<wsdl:portType name="HelloWorld">
<wsdl:operation name="sayHello">
<wsdl:input message="tns:sayHello"/>
<wsdl:output message="tns:sayHelloResponse"/>
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="HelloWorld" type="tns:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello"><soap:operation soapAction="sayHello"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body/></wsdl:output></wsdl:operation>
</wsdl:binding>

<wsdl:service name="HelloWorld">
<wsdl:port name="HelloWorld" binding="tns:HelloWorld">
<soap:address location="http://my.fake.url"/>
</wsdl:port>
</wsdl:service>

</wsdl:definitions>


src/xsd/person.xsd



<?xml version='1.0' encoding='UTF-8'?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="http://types.myapp/person/"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="person">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="surname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>


src/main/java/myapp/service/HelloWorld.java



package myapp.service;

import javax.jws.WebService;
import myapp.legacy.model.LegacyPerson;

@WebService(
endpointInterface = "myapp.service.helloworld.HelloWorld",
wsdlLocation = "wsdl/hello_world.wsdl"
)
public class HelloWorld implements myapp.service.helloworld.HelloWorld {

@Override
public String sayHello(LegacyPerson who) {
return "Hello " + who.getLegacyName() + " " + who.getLegacySurname();
}

}


src/main/java/myapp/legacy/model/LegacyPerson.java



package myapp.legacy.model;

public class LegacyPerson {
private String legacyName;
private String legacySurname;

public String getLegacyName() {
return legacyName;
}

public void setLegacyName(String legacyName) {
this.legacyName = legacyName;
}

public String getLegacySurname() {
return legacySurname;
}

public void setLegacySurname(String legacySurname) {
this.legacySurname = legacySurname;
}
}


src/jaxws/bindings.xml



<jaxb:bindings version="2.0"
xmlns:jaxb ="http://java.sun.com/xml/ns/jaxb"
xmlns:xs ="http://www.w3.org/2001/XMLSchema"
schemaLocation="../xsd/person.xsd"
>
<jaxb:bindings node="/xs:schema/xs:complexType[@name='person']">
<jaxb:class ref="myapp.legacy.model.LegacyPerson"/><!-- Make the SEI use my legacy model, but how should I describe how to bind the data? -->

<!-- This will make wsimport say : "compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings." -->
<!-- <jaxb:bindings node="//xs:element[@name='name']">
<jaxb:property name="legacyName" />
</jaxb:bindings>-->
</jaxb:bindings>

</jaxb:bindings>




References




  • https://javaee.github.io/metro-jax-ws/doc/user-guide/

  • https://download.oracle.com/otn-pub/jcp/jaxb-2_3-mrel3-eval-spec/JAXB-2.3-spec.pdf

  • https://download.oracle.com/otn-pub/jcp/websvcs_metadata-2_1-mrel2-eval-spec/JSR181-2.1-MR.pdf

  • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-jws.htm#WSGET156

  • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#GUID-2C55847C-0990-4763-8041-EECE802A7EB1

  • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#WSGET212

  • http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html


  • JAX-WS & JAX-RS with EclipseLink MOXy and external mapping documents










share|improve this question



























    0















    I am preparing to migrate SOAP web services from JAX-RPC to JAX-WS.
    It has to be as smooth as possible:




    • WSDL must not be modified.

    • New JAX-WS web services should use the same implementation as their old JAX-RPC counterparts (maximum reuse of code, no copy/paste).

    • New JAX-WS web services should be able to operate in parallel with their old JAX-RPC counterparts.


    How it is working today:




    • Existing WSDL are generated from the JAX-RPC @WebService classes,

    • XML schemas are hand-written, and compiled by XMLBeans.

    • At runtime, XMLBeans objects are converted into model objects by hand-written *Converter classes.


    How we want to make it work after the migration:




    • New JAX-WS web services will be contract-first: Service Endpoint Interfaces (SEI) will be generated from existing WSDL.

    • XML types should be binded directly to existing model objects.

    • Binding configuration should be external (not use annotations).


    I am using wsimport goal from jaxws-maven-plugin (http://www.mojohaus.org/jaxws-maven-plugin/) to generate Java code from WSDL.
    The services will be deployed as a web app (not EJB) in WebLogic Server 12.2.1.3.



    I tried without success to use:




    • JAX-WS and JAXB binding customizations


      • WLS doc says that "If customizations are required, Oracle recommends [creating external binding] to maintain flexibility by keeping the customizations separate from the WSDL or XML Schema document.")

      • it seems that I have to use annotations, and I couldn't find a way to use XmlAdapters without modifying model objects (to add XmlJavaTypeAdapter).



    • EclipseLink MOXy external binding (EclipseLink MOXy is the default data binding and JAXB provider in WLS12.2.1.3).


      • The doc states that "EclipseLink MOXy provides (...) the ability to use an external metadata file to configure the equivalent of JAXB annotations without modifying the Java source it refers to"

      • but says also that "EclipseLink MOXy extensions can be leveraged (...) only in the Java to WSDL scenario".

      • as a matter of fact I couldn't manage to have maven tooling nor the app to use this binding.




    Put in code, it looks like:



    pom.xml



    <?xml version="1.0" encoding="UTF-8"?>
    <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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>myapp</artifactId>
    <packaging>war</packaging>

    <groupId>sandbox.jaxws_migration</groupId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
    </properties>

    <dependencies>
    <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
    </dependency>
    </dependencies>

    <build>
    <pluginManagement>
    <plugins>
    <plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin>
    </plugins>
    </pluginManagement>
    <plugins>
    <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jaxws-maven-plugin</artifactId>
    <version>2.5</version>
    <dependencies>
    <dependency>
    <groupId>org.glassfish.metro</groupId>
    <artifactId>webservices-tools</artifactId>
    <version>2.3.1</version>
    </dependency>
    <!-- see https://java.net/jira/browse/WSIT-1672 -->
    <dependency>
    <groupId>org.glassfish.metro</groupId>
    <artifactId>webservices-rt</artifactId>
    <version>2.3.1</version>
    </dependency>
    </dependencies>
    <executions>
    <execution>
    <goals>
    <goal>wsimport</goal>
    </goals>
    <configuration>
    <xadditionalHeaders>true</xadditionalHeaders>
    <verbose>true</verbose>
    </configuration>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>

    </project>


    src/wsdl/hello_world.wsdl



    <?xml version='1.0' encoding='UTF-8'?>
    <wsdl:definitions name="HelloWorld"
    targetNamespace="http://service.myapp/helloworld/"
    xmlns:tns ="http://service.myapp/helloworld/"
    xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xs ="http://www.w3.org/2001/XMLSchema"
    xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"
    xmlns:p ="http://types.myapp/person/"
    >

    <wsdl:types>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://service.myapp/helloworld/">
    <xs:import namespace="http://types.myapp/person/" schemaLocation="../xsd/person.xsd"/>
    <xs:element name="sayHello">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="who" type="p:person"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    <xs:element name="sayHelloResponse">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="greetings" type="xs:string">
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:schema>
    </wsdl:types>

    <wsdl:message name="sayHello"> <wsdl:part name="p" element="tns:sayHello"/> </wsdl:message>
    <wsdl:message name="sayHelloResponse"><wsdl:part name="p" element="tns:sayHelloResponse"/></wsdl:message>

    <wsdl:portType name="HelloWorld">
    <wsdl:operation name="sayHello">
    <wsdl:input message="tns:sayHello"/>
    <wsdl:output message="tns:sayHelloResponse"/>
    </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="HelloWorld" type="tns:HelloWorld">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="sayHello"><soap:operation soapAction="sayHello"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body/></wsdl:output></wsdl:operation>
    </wsdl:binding>

    <wsdl:service name="HelloWorld">
    <wsdl:port name="HelloWorld" binding="tns:HelloWorld">
    <soap:address location="http://my.fake.url"/>
    </wsdl:port>
    </wsdl:service>

    </wsdl:definitions>


    src/xsd/person.xsd



    <?xml version='1.0' encoding='UTF-8'?>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
    targetNamespace="http://types.myapp/person/"
    xmlns:xs ="http://www.w3.org/2001/XMLSchema"
    >
    <xs:complexType name="person">
    <xs:sequence>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="surname" type="xs:string"/>
    </xs:sequence>
    </xs:complexType>
    </xs:schema>


    src/main/java/myapp/service/HelloWorld.java



    package myapp.service;

    import javax.jws.WebService;
    import myapp.legacy.model.LegacyPerson;

    @WebService(
    endpointInterface = "myapp.service.helloworld.HelloWorld",
    wsdlLocation = "wsdl/hello_world.wsdl"
    )
    public class HelloWorld implements myapp.service.helloworld.HelloWorld {

    @Override
    public String sayHello(LegacyPerson who) {
    return "Hello " + who.getLegacyName() + " " + who.getLegacySurname();
    }

    }


    src/main/java/myapp/legacy/model/LegacyPerson.java



    package myapp.legacy.model;

    public class LegacyPerson {
    private String legacyName;
    private String legacySurname;

    public String getLegacyName() {
    return legacyName;
    }

    public void setLegacyName(String legacyName) {
    this.legacyName = legacyName;
    }

    public String getLegacySurname() {
    return legacySurname;
    }

    public void setLegacySurname(String legacySurname) {
    this.legacySurname = legacySurname;
    }
    }


    src/jaxws/bindings.xml



    <jaxb:bindings version="2.0"
    xmlns:jaxb ="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs ="http://www.w3.org/2001/XMLSchema"
    schemaLocation="../xsd/person.xsd"
    >
    <jaxb:bindings node="/xs:schema/xs:complexType[@name='person']">
    <jaxb:class ref="myapp.legacy.model.LegacyPerson"/><!-- Make the SEI use my legacy model, but how should I describe how to bind the data? -->

    <!-- This will make wsimport say : "compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings." -->
    <!-- <jaxb:bindings node="//xs:element[@name='name']">
    <jaxb:property name="legacyName" />
    </jaxb:bindings>-->
    </jaxb:bindings>

    </jaxb:bindings>




    References




    • https://javaee.github.io/metro-jax-ws/doc/user-guide/

    • https://download.oracle.com/otn-pub/jcp/jaxb-2_3-mrel3-eval-spec/JAXB-2.3-spec.pdf

    • https://download.oracle.com/otn-pub/jcp/websvcs_metadata-2_1-mrel2-eval-spec/JSR181-2.1-MR.pdf

    • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-jws.htm#WSGET156

    • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#GUID-2C55847C-0990-4763-8041-EECE802A7EB1

    • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#WSGET212

    • http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html


    • JAX-WS & JAX-RS with EclipseLink MOXy and external mapping documents










    share|improve this question

























      0












      0








      0








      I am preparing to migrate SOAP web services from JAX-RPC to JAX-WS.
      It has to be as smooth as possible:




      • WSDL must not be modified.

      • New JAX-WS web services should use the same implementation as their old JAX-RPC counterparts (maximum reuse of code, no copy/paste).

      • New JAX-WS web services should be able to operate in parallel with their old JAX-RPC counterparts.


      How it is working today:




      • Existing WSDL are generated from the JAX-RPC @WebService classes,

      • XML schemas are hand-written, and compiled by XMLBeans.

      • At runtime, XMLBeans objects are converted into model objects by hand-written *Converter classes.


      How we want to make it work after the migration:




      • New JAX-WS web services will be contract-first: Service Endpoint Interfaces (SEI) will be generated from existing WSDL.

      • XML types should be binded directly to existing model objects.

      • Binding configuration should be external (not use annotations).


      I am using wsimport goal from jaxws-maven-plugin (http://www.mojohaus.org/jaxws-maven-plugin/) to generate Java code from WSDL.
      The services will be deployed as a web app (not EJB) in WebLogic Server 12.2.1.3.



      I tried without success to use:




      • JAX-WS and JAXB binding customizations


        • WLS doc says that "If customizations are required, Oracle recommends [creating external binding] to maintain flexibility by keeping the customizations separate from the WSDL or XML Schema document.")

        • it seems that I have to use annotations, and I couldn't find a way to use XmlAdapters without modifying model objects (to add XmlJavaTypeAdapter).



      • EclipseLink MOXy external binding (EclipseLink MOXy is the default data binding and JAXB provider in WLS12.2.1.3).


        • The doc states that "EclipseLink MOXy provides (...) the ability to use an external metadata file to configure the equivalent of JAXB annotations without modifying the Java source it refers to"

        • but says also that "EclipseLink MOXy extensions can be leveraged (...) only in the Java to WSDL scenario".

        • as a matter of fact I couldn't manage to have maven tooling nor the app to use this binding.




      Put in code, it looks like:



      pom.xml



      <?xml version="1.0" encoding="UTF-8"?>
      <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <artifactId>myapp</artifactId>
      <packaging>war</packaging>

      <groupId>sandbox.jaxws_migration</groupId>
      <version>1.0.0-SNAPSHOT</version>

      <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
      </properties>

      <dependencies>
      <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
      </dependency>
      </dependencies>

      <build>
      <pluginManagement>
      <plugins>
      <plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin>
      </plugins>
      </pluginManagement>
      <plugins>
      <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>jaxws-maven-plugin</artifactId>
      <version>2.5</version>
      <dependencies>
      <dependency>
      <groupId>org.glassfish.metro</groupId>
      <artifactId>webservices-tools</artifactId>
      <version>2.3.1</version>
      </dependency>
      <!-- see https://java.net/jira/browse/WSIT-1672 -->
      <dependency>
      <groupId>org.glassfish.metro</groupId>
      <artifactId>webservices-rt</artifactId>
      <version>2.3.1</version>
      </dependency>
      </dependencies>
      <executions>
      <execution>
      <goals>
      <goal>wsimport</goal>
      </goals>
      <configuration>
      <xadditionalHeaders>true</xadditionalHeaders>
      <verbose>true</verbose>
      </configuration>
      </execution>
      </executions>
      </plugin>
      </plugins>
      </build>

      </project>


      src/wsdl/hello_world.wsdl



      <?xml version='1.0' encoding='UTF-8'?>
      <wsdl:definitions name="HelloWorld"
      targetNamespace="http://service.myapp/helloworld/"
      xmlns:tns ="http://service.myapp/helloworld/"
      xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:p ="http://types.myapp/person/"
      >

      <wsdl:types>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://service.myapp/helloworld/">
      <xs:import namespace="http://types.myapp/person/" schemaLocation="../xsd/person.xsd"/>
      <xs:element name="sayHello">
      <xs:complexType>
      <xs:sequence>
      <xs:element name="who" type="p:person"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      <xs:element name="sayHelloResponse">
      <xs:complexType>
      <xs:sequence>
      <xs:element name="greetings" type="xs:string">
      </xs:element>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      </xs:schema>
      </wsdl:types>

      <wsdl:message name="sayHello"> <wsdl:part name="p" element="tns:sayHello"/> </wsdl:message>
      <wsdl:message name="sayHelloResponse"><wsdl:part name="p" element="tns:sayHelloResponse"/></wsdl:message>

      <wsdl:portType name="HelloWorld">
      <wsdl:operation name="sayHello">
      <wsdl:input message="tns:sayHello"/>
      <wsdl:output message="tns:sayHelloResponse"/>
      </wsdl:operation>
      </wsdl:portType>

      <wsdl:binding name="HelloWorld" type="tns:HelloWorld">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="sayHello"><soap:operation soapAction="sayHello"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body/></wsdl:output></wsdl:operation>
      </wsdl:binding>

      <wsdl:service name="HelloWorld">
      <wsdl:port name="HelloWorld" binding="tns:HelloWorld">
      <soap:address location="http://my.fake.url"/>
      </wsdl:port>
      </wsdl:service>

      </wsdl:definitions>


      src/xsd/person.xsd



      <?xml version='1.0' encoding='UTF-8'?>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
      targetNamespace="http://types.myapp/person/"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      >
      <xs:complexType name="person">
      <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="surname" type="xs:string"/>
      </xs:sequence>
      </xs:complexType>
      </xs:schema>


      src/main/java/myapp/service/HelloWorld.java



      package myapp.service;

      import javax.jws.WebService;
      import myapp.legacy.model.LegacyPerson;

      @WebService(
      endpointInterface = "myapp.service.helloworld.HelloWorld",
      wsdlLocation = "wsdl/hello_world.wsdl"
      )
      public class HelloWorld implements myapp.service.helloworld.HelloWorld {

      @Override
      public String sayHello(LegacyPerson who) {
      return "Hello " + who.getLegacyName() + " " + who.getLegacySurname();
      }

      }


      src/main/java/myapp/legacy/model/LegacyPerson.java



      package myapp.legacy.model;

      public class LegacyPerson {
      private String legacyName;
      private String legacySurname;

      public String getLegacyName() {
      return legacyName;
      }

      public void setLegacyName(String legacyName) {
      this.legacyName = legacyName;
      }

      public String getLegacySurname() {
      return legacySurname;
      }

      public void setLegacySurname(String legacySurname) {
      this.legacySurname = legacySurname;
      }
      }


      src/jaxws/bindings.xml



      <jaxb:bindings version="2.0"
      xmlns:jaxb ="http://java.sun.com/xml/ns/jaxb"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      schemaLocation="../xsd/person.xsd"
      >
      <jaxb:bindings node="/xs:schema/xs:complexType[@name='person']">
      <jaxb:class ref="myapp.legacy.model.LegacyPerson"/><!-- Make the SEI use my legacy model, but how should I describe how to bind the data? -->

      <!-- This will make wsimport say : "compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings." -->
      <!-- <jaxb:bindings node="//xs:element[@name='name']">
      <jaxb:property name="legacyName" />
      </jaxb:bindings>-->
      </jaxb:bindings>

      </jaxb:bindings>




      References




      • https://javaee.github.io/metro-jax-ws/doc/user-guide/

      • https://download.oracle.com/otn-pub/jcp/jaxb-2_3-mrel3-eval-spec/JAXB-2.3-spec.pdf

      • https://download.oracle.com/otn-pub/jcp/websvcs_metadata-2_1-mrel2-eval-spec/JSR181-2.1-MR.pdf

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-jws.htm#WSGET156

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#GUID-2C55847C-0990-4763-8041-EECE802A7EB1

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#WSGET212

      • http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html


      • JAX-WS & JAX-RS with EclipseLink MOXy and external mapping documents










      share|improve this question














      I am preparing to migrate SOAP web services from JAX-RPC to JAX-WS.
      It has to be as smooth as possible:




      • WSDL must not be modified.

      • New JAX-WS web services should use the same implementation as their old JAX-RPC counterparts (maximum reuse of code, no copy/paste).

      • New JAX-WS web services should be able to operate in parallel with their old JAX-RPC counterparts.


      How it is working today:




      • Existing WSDL are generated from the JAX-RPC @WebService classes,

      • XML schemas are hand-written, and compiled by XMLBeans.

      • At runtime, XMLBeans objects are converted into model objects by hand-written *Converter classes.


      How we want to make it work after the migration:




      • New JAX-WS web services will be contract-first: Service Endpoint Interfaces (SEI) will be generated from existing WSDL.

      • XML types should be binded directly to existing model objects.

      • Binding configuration should be external (not use annotations).


      I am using wsimport goal from jaxws-maven-plugin (http://www.mojohaus.org/jaxws-maven-plugin/) to generate Java code from WSDL.
      The services will be deployed as a web app (not EJB) in WebLogic Server 12.2.1.3.



      I tried without success to use:




      • JAX-WS and JAXB binding customizations


        • WLS doc says that "If customizations are required, Oracle recommends [creating external binding] to maintain flexibility by keeping the customizations separate from the WSDL or XML Schema document.")

        • it seems that I have to use annotations, and I couldn't find a way to use XmlAdapters without modifying model objects (to add XmlJavaTypeAdapter).



      • EclipseLink MOXy external binding (EclipseLink MOXy is the default data binding and JAXB provider in WLS12.2.1.3).


        • The doc states that "EclipseLink MOXy provides (...) the ability to use an external metadata file to configure the equivalent of JAXB annotations without modifying the Java source it refers to"

        • but says also that "EclipseLink MOXy extensions can be leveraged (...) only in the Java to WSDL scenario".

        • as a matter of fact I couldn't manage to have maven tooling nor the app to use this binding.




      Put in code, it looks like:



      pom.xml



      <?xml version="1.0" encoding="UTF-8"?>
      <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/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>

      <artifactId>myapp</artifactId>
      <packaging>war</packaging>

      <groupId>sandbox.jaxws_migration</groupId>
      <version>1.0.0-SNAPSHOT</version>

      <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

      <maven.compiler.source>1.8</maven.compiler.source>
      <maven.compiler.target>${maven.compiler.source}</maven.compiler.target>
      </properties>

      <dependencies>
      <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
      </dependency>
      </dependencies>

      <build>
      <pluginManagement>
      <plugins>
      <plugin><artifactId>maven-war-plugin</artifactId><version>3.2.2</version></plugin>
      </plugins>
      </pluginManagement>
      <plugins>
      <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>jaxws-maven-plugin</artifactId>
      <version>2.5</version>
      <dependencies>
      <dependency>
      <groupId>org.glassfish.metro</groupId>
      <artifactId>webservices-tools</artifactId>
      <version>2.3.1</version>
      </dependency>
      <!-- see https://java.net/jira/browse/WSIT-1672 -->
      <dependency>
      <groupId>org.glassfish.metro</groupId>
      <artifactId>webservices-rt</artifactId>
      <version>2.3.1</version>
      </dependency>
      </dependencies>
      <executions>
      <execution>
      <goals>
      <goal>wsimport</goal>
      </goals>
      <configuration>
      <xadditionalHeaders>true</xadditionalHeaders>
      <verbose>true</verbose>
      </configuration>
      </execution>
      </executions>
      </plugin>
      </plugins>
      </build>

      </project>


      src/wsdl/hello_world.wsdl



      <?xml version='1.0' encoding='UTF-8'?>
      <wsdl:definitions name="HelloWorld"
      targetNamespace="http://service.myapp/helloworld/"
      xmlns:tns ="http://service.myapp/helloworld/"
      xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"
      xmlns:p ="http://types.myapp/person/"
      >

      <wsdl:types>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://service.myapp/helloworld/">
      <xs:import namespace="http://types.myapp/person/" schemaLocation="../xsd/person.xsd"/>
      <xs:element name="sayHello">
      <xs:complexType>
      <xs:sequence>
      <xs:element name="who" type="p:person"/>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      <xs:element name="sayHelloResponse">
      <xs:complexType>
      <xs:sequence>
      <xs:element name="greetings" type="xs:string">
      </xs:element>
      </xs:sequence>
      </xs:complexType>
      </xs:element>
      </xs:schema>
      </wsdl:types>

      <wsdl:message name="sayHello"> <wsdl:part name="p" element="tns:sayHello"/> </wsdl:message>
      <wsdl:message name="sayHelloResponse"><wsdl:part name="p" element="tns:sayHelloResponse"/></wsdl:message>

      <wsdl:portType name="HelloWorld">
      <wsdl:operation name="sayHello">
      <wsdl:input message="tns:sayHello"/>
      <wsdl:output message="tns:sayHelloResponse"/>
      </wsdl:operation>
      </wsdl:portType>

      <wsdl:binding name="HelloWorld" type="tns:HelloWorld">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
      <wsdl:operation name="sayHello"><soap:operation soapAction="sayHello"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body/></wsdl:output></wsdl:operation>
      </wsdl:binding>

      <wsdl:service name="HelloWorld">
      <wsdl:port name="HelloWorld" binding="tns:HelloWorld">
      <soap:address location="http://my.fake.url"/>
      </wsdl:port>
      </wsdl:service>

      </wsdl:definitions>


      src/xsd/person.xsd



      <?xml version='1.0' encoding='UTF-8'?>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
      targetNamespace="http://types.myapp/person/"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      >
      <xs:complexType name="person">
      <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="surname" type="xs:string"/>
      </xs:sequence>
      </xs:complexType>
      </xs:schema>


      src/main/java/myapp/service/HelloWorld.java



      package myapp.service;

      import javax.jws.WebService;
      import myapp.legacy.model.LegacyPerson;

      @WebService(
      endpointInterface = "myapp.service.helloworld.HelloWorld",
      wsdlLocation = "wsdl/hello_world.wsdl"
      )
      public class HelloWorld implements myapp.service.helloworld.HelloWorld {

      @Override
      public String sayHello(LegacyPerson who) {
      return "Hello " + who.getLegacyName() + " " + who.getLegacySurname();
      }

      }


      src/main/java/myapp/legacy/model/LegacyPerson.java



      package myapp.legacy.model;

      public class LegacyPerson {
      private String legacyName;
      private String legacySurname;

      public String getLegacyName() {
      return legacyName;
      }

      public void setLegacyName(String legacyName) {
      this.legacyName = legacyName;
      }

      public String getLegacySurname() {
      return legacySurname;
      }

      public void setLegacySurname(String legacySurname) {
      this.legacySurname = legacySurname;
      }
      }


      src/jaxws/bindings.xml



      <jaxb:bindings version="2.0"
      xmlns:jaxb ="http://java.sun.com/xml/ns/jaxb"
      xmlns:xs ="http://www.w3.org/2001/XMLSchema"
      schemaLocation="../xsd/person.xsd"
      >
      <jaxb:bindings node="/xs:schema/xs:complexType[@name='person']">
      <jaxb:class ref="myapp.legacy.model.LegacyPerson"/><!-- Make the SEI use my legacy model, but how should I describe how to bind the data? -->

      <!-- This will make wsimport say : "compiler was unable to honor this property customization. It is attached to a wrong place, or its inconsistent with other bindings." -->
      <!-- <jaxb:bindings node="//xs:element[@name='name']">
      <jaxb:property name="legacyName" />
      </jaxb:bindings>-->
      </jaxb:bindings>

      </jaxb:bindings>




      References




      • https://javaee.github.io/metro-jax-ws/doc/user-guide/

      • https://download.oracle.com/otn-pub/jcp/jaxb-2_3-mrel3-eval-spec/JAXB-2.3-spec.pdf

      • https://download.oracle.com/otn-pub/jcp/websvcs_metadata-2_1-mrel2-eval-spec/JSR181-2.1-MR.pdf

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-jws.htm#WSGET156

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#GUID-2C55847C-0990-4763-8041-EECE802A7EB1

      • https://docs.oracle.com/middleware/12213/wls/WSGET/jax-ws-datatypes.htm#WSGET212

      • http://blog.bdoughan.com/2010/12/extending-jaxb-representing-annotations.html


      • JAX-WS & JAX-RS with EclipseLink MOXy and external mapping documents







      java web-services jaxb eclipselink jax-ws-customization






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 26 '18 at 13:27









      Romain BuquetRomain Buquet

      14614




      14614
























          0






          active

          oldest

          votes











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53482156%2fis-it-possible-to-migrate-existing-jax-rpc-web-services-to-jax-ws-without-any-ws%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes
















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53482156%2fis-it-possible-to-migrate-existing-jax-rpc-web-services-to-jax-ws-without-any-ws%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Contact image not getting when fetch all contact list from iPhone by CNContact

          count number of partitions of a set with n elements into k subsets

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks