16

The XPath expression in my external binding files can't target the elements in my XML schemas which are imported into my WSDL.

Everything runs if I do inline binding customization but I really wanted to have external binding files that way I never accidentally overwrite(refresh) the files containing my customizations.

The start of my binding file:

<jaxb:bindings
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
    version="2.1">
    <jaxb:bindings schemaLocation="../wsdl/localhost_7001/ExampleSessionBean/ExampleSessionBeanService.wsdl#types?schema1">
        <jaxb:bindings node="//xs:schema[@targetNamespace='urn:myExample']">

My WSDL contains:

<types>
<xsd:schema>
<xsd:import namespace="urn:myExample" schemaLocation="http://localhost:7001/ExampleSessionBean/ExampleSessionBeanService?xsd=1"/>
</xsd:schema>
<xsd:schema>
<xsd:import namespace="http://ejbs/" schemaLocation="http://localhost:7001/ExampleSessionBean/ExampleSessionBeanService?xsd=2"/>
</xsd:schema>
</types>

No matter what I do XPath can't find anything in the xsd:import'ed schemas. The error I get is:

[ERROR] XPath evaluation of "//xs:schema[@targetNamespace='urn:myExample']" results in empty target node

I've tried accessing the xs:schema by index number instead of the namespace and that doesn't work either. It seems like my XPath expressions can't reach elements from imported schemas...is there anyway to fix this?

This is a Java SE 7 project being developed under NetBean 7.2. I'm using NetBeans to do all my wsimport stuff if that matters but the command output looks fairly standard for RI/Metro.

EDIT: I figured out that I can get an external binding file to work if I use SCD. This XPath example doesn't work:

<bindings node="//xsd:schema[@targetNamespace='urn:myExample']">
    <bindings node="//xs:complexType[@name='myType']">
        <class name="MyClass"/>
    </bindings>
</bindings>

But this SCD example does.

<bindings scd="x-schema::tns" xmlns:tns="urn:myExample">
    <bindings scd="~tns:myType">
        <class name="MyClass"/>
    </bindings>
</bindings>

Is this a known thing where XPath doesn't work in xjb files when using wsimport but SCD does?

Chase
  • 2,933
  • 1
  • 26
  • 33
  • I tried this. But now I get the following error `SCD "~tns:myelement" didnt match any schema component` – wib Sep 11 '15 at 06:01

4 Answers4

9

you should use it like:

<jaxws:bindings node="wsdl:definitions/wsdl:types/xsd:schema[@targetNamespace='http://duke.example.org']">
    <jaxb:schemaBindings>
        <jaxb:package name="fromwsdl.server"/>
    </jaxb:schemaBindings>
</jaxws:bindings>

Be careful with the namespaces

It all is explained here: https://jax-ws.java.net/nonav/2.1.2/docs/customizations.html

elro
  • 99
  • 1
  • 1
    I'm looking to customize the JAXB artifacts, not the JAX-WS artifacts. I'd not trying to change the service class name, I'm trying to change the complex parameter class names. If you look at http://docs.oracle.com/javase/6/docs/technotes/tools/share/wsimport.html you'll see that wsimport -b can take either a JAX-WS or JAXB binding file. I'm trying to use a JAXB binding file. – Chase Apr 23 '13 at 16:03
  • This looked good first, but for some reason the XPath won't select any nodes. How do you debug the XPath result with (inside) this tool? How do I tell it _"print everything you see"_? _Update_: I found a mistake in my binding, I was using `jaxb:bindings` instead of `jaxb:schemaBindings`. The XPath compiles now. – aliopi Oct 31 '17 at 09:15
  • That _java.net_-URL doesn't work, did you mean https://javaee.github.io/metro-jax-ws/doc/user-guide/ch03.html#users-guide-wsdl-customization ? – aliopi Oct 31 '17 at 09:35
5

You could compile each of the XML schemas to Java classes individually. Then you can leverage episode files so that the generated classes can be used when you compile schemas that import that XML schema.

Below is an example of how you produce an episode file.

xjc -b binding1.xml -episode common.episode common.xsd

And below is an example of how you consume and episode file. The episode file is just a JAXB external bindings file and therefore is specified using the -b flag.

xjc -d out main.xsd -extension -b common.episode   

For More Information

bdoughan
  • 142,244
  • 22
  • 280
  • 377
  • 2
    The classes aren't really reused so I don't have a need to precompile them. I tried it anyway and I noticed the episode files are using SCD instead of XPath. It looks like I can use SCD in an external binding file. Awarding you the bounty because your answer helped me with a work around. – Chase Mar 02 '13 at 19:11
  • 1
    I'm not suggesting you shouldn't award the bounty; it's your bounty. But this is not really an answer to the question. – Cheeso Mar 19 '13 at 20:40
2

For new people, you can simply use two binding files, one applied to wsdl and other applied to the schema by using the -b option of wsdl2java cxf code generation class accepts multiple binding files:

<java classname="org.apache.cxf.tools.wsdlto.WSDLToJava" fork="true">
    <arg value="-d"/>
    <arg value="${src}"/>
    <arg value="-b"/>
    <arg value="${wsdl.home}\jaxws-bindings.xml"/>
    <arg value="-b"/>
    <arg value="${wsdl.home}\jaxb-bindings.xml"/>
    <arg value="${wsdl.home}\YOUR_WSDL.wsdl"/>
    <classpath>
        <path refid="cxf.classpath"/>
    </classpath>
</java>

Content of file 'jaxws-bindings.xml':

<jaxws:bindings wsdlLocation="YOUR_WSDL.wsdl"
                xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
                xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>

Content of 'jaxb-bindings.xml':

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
               jaxb:version="2.0">
    <jaxb:bindings schemaLocation="ManagePartyCustomerDataManagement_PARTY_G7-IOP_In_1.0.xsd">
        <jaxb:bindings node="//xsd:element[@name='eventDate']">
            <jaxb:javaType name="java.util.Date" 
                       parseMethod="com.sofrecom.gaia.ebs.provider.utils.jaxb.StringDateAdapter.parseDate"
                       printMethod="com.sofrecom.gaia.ebs.provider.utils.jaxb.StringDateAdapter.printDate" />
  </jaxb:bindings>

Peter Becker
  • 8,405
  • 7
  • 38
  • 59
najib.bey
  • 21
  • 1
1

Adding this section to my JAXB configuration helped to do away with a similar error:

<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
   <jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle>
   <jaxws:enableAsyncMapping>false</jaxws:enableAsyncMapping>
</jaxws:bindings>

Complete configuration:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="2.1" 
                xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
                xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
        <jaxws:enableWrapperStyle>true</jaxws:enableWrapperStyle>
        <jaxws:enableAsyncMapping>false</jaxws:enableAsyncMapping>
    </jaxws:bindings>

    <jaxb:bindings schemaLocation="ContactService.wsdl" node="/wsdl:definitions/wsdl:types/xs:schema">
        <jaxb:schemaBindings>
            <jaxb:package name="za.org.kuali.kfs.sys.integration.iapi.contactservice"/>
        </jaxb:schemaBindings>
    </jaxb:bindings>

</jaxb:bindings>

Credits:

xilef
  • 1,428
  • 17
  • 12