Apache CXF wsdl2java InternalError: unresolved reference - web-services

I'm trying to generate Java sources for a Web Service with Apache CXF wsdl2java executable (I've tried 2.7.8 and 3.2.0 versions).
My wsdl file come from an external agency (TMDD), so I assume is well generated
When I tried to generate files first time, a "Non-unique body parts" error occur:
org.apache.cxf.tools.common.ToolException: Non-unique body parts! In a port, operations must have unique operation signatures on the wire for successful dispatching. In port {http://www.tmdd.org/303/dialogs}tmddOCSoapHttpServicePort, operations "{http://www.tmdd.org/303/dialogs}dlVideoSwitchStatusRequest" and "{http://www.tmdd.org/303/dialogs}dlIntersectionSignalStatusRequest" have the same request body block {http://www.tmdd.org/303/messages}deviceInformationRequestMsg
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.validate(WSDLToJavaContainer.java:735)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:276)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
I solved it creating a new input message type in dlVideoSwitchStatusRequest operation to avoid this. My steps were:
Create a new message type
<message name="MSG_VideoSwitchStatusRequest">
<part name="message" element="tmdd:videoSwitchStatusRequestMsg"/>
</message>
Declare videoSwitchStatusRequestMsg
<xs:element name="videoSwitchStatusRequestMsg" type="VideoSwitchStatusRequest">
<xs:annotation>
<xs:documentation>
<objectClass>VideoSwitch</objectClass>
<requirement>REQ1109</requirement>
</xs:documentation>
</xs:annotation>
</xs:element>
This one is defined in .xsd file as similar ones for other operations.
Modify input type for that operation
<operation name="dlVideoSwitchStatusRequest">
<documentation><objectClass>VideoSwitch</objectClass><objectClass>ExternalCenter</objectClass><objectClass>OwnerCenter</objectClass><msgPattern>R-R</msgPattern><requirement>REQ538</requirement></documentation>
<input message="tns:MSG_VideoSwitchStatusRequest"/> <!-- This is the new type -->
<!--<input message="tns:MSG_DeviceInformationRequest"/> This is the old one -->
<output message="tns:MSG_VideoSwitchStatus"/>
<fault name="errorReport" message="tns:MSG_ErrorReport"/>
</operation>
With this, that error was solved (i think), but now i get another error
Exception in thread "main" java.lang.InternalError: unresolved reference
at com.sun.xml.xsom.impl.parser.DelayedRef._get(DelayedRef.java:103)
at com.sun.xml.xsom.impl.parser.DelayedRef$Type.getType(DelayedRef.java:148)
at com.sun.xml.xsom.impl.ElementDecl.getType(ElementDecl.java:110)
at com.sun.xml.xsom.impl.ElementDecl.updateSubstitutabilityMap(ElementDecl.java:174)
at com.sun.xml.xsom.impl.parser.ParserContext.getResult(ParserContext.java:141)
at com.sun.xml.xsom.parser.XSOMParser.getResult(XSOMParser.java:214)
at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:538)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:269)
at com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:95)
at org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:459)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.generateTypes(WSDLToJavaContainer.java:723)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:267)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:164)
at org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:412)
at org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:105)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:113)
at org.apache.cxf.tools.wsdlto.WSDLToJava.run(WSDLToJava.java:86)
at org.apache.cxf.tools.wsdlto.WSDLToJava.main(WSDLToJava.java:185)
This one is too generic and I didn't found any info or doc from Apache site.

First, you must no assume the TMDD wsdl is well generated. I worked with it some time ago and is plenty of errors.
I recommend you to re-create your own version of TMDD.wsdl file, limiting it only to those items you're going to use.
Try that and tell us what you got.

Well, as B. Leal suggest, i drop old tmdd.wsdl and re-do my wsdl files with separate files for each device i will need data for.
As most work has been re-done, i'm not 100% sure about where that error came from, but i'm pretty sure that it was related with some types used in the old wsdl that wasn't declared properly in xsd files.
I know this is not a big help, but if someone falls in this same error, i think you only have two choices:
Re-do your wsdl files, as i did. (I recommend this one, it's easier than it seems)
Check if every single type used in wsdl are present in xsd files and if they're correct.
Thanks for help.

I had the same problem and mine was in XSD. Forgot to add namespace before type. tns and targetNamespace are the same url.
Before:
<xs:element name="getRequest" type="Request">
After
<xs:element name="getRequest" type="tns:Request">
This simple change in all elements using complexType/simpleType fixed the problem.

Related

WCF SOAP, WSDL defines a integer parameter, but service demands a blank. How?

So, I am tasked with integrating with a 3rd party web service. The WSDL for the service has an operation, where the input parameter is defined like so (variable names changed for anonymity/legality) :
<xs:complexType name="RequestData_Type">
<xs:sequence>
<xs:element name="A" type="tns:string8"/>
<xs:element name="B" type="tns:integer11"/>
<xs:element name="C" type="tns:integer11"/>
<xs:element name="D" type="tns:string21"/>
<xs:element name="E" type="tns:string13"/>
</xs:sequence>
</xs:complexType>
Integer11 is defined as :
<xs:simpleType name="integer11">
<xs:restriction base="xs:long">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="99999999999"/>
</xs:restriction>
</xs:simpleType>
When I imported this WSDL into visual studio (Add Web Reference), it generated a proxy class that has the following fields (properties excluded for readability)
public partial class RequestData_Type : object, System.ComponentModel.INotifyPropertyChanged {
private string A;
private long B;
private long C;
private string D;
private string E;
And finally, the message that the web service ACTUALLY wants to receive is
<RequestData>
<A>SomeData</A>
<B> </B>
<C> </C>
<D> </D>
<E>SomeData</E>
</RequestData>
So, In my opinion, this is completely invalid, because B and C are defined as integers, are not defined as nillable, and are not defined as MinOccurs=0
I raised this issue to the 3rd party that owns the service/wsdl and they basically replied back as : "Nobody else has problems, deal with it, we suggest turning off schema validation". Joy.
So steps to resolve :
I tried manually tweaking the proxy to be "long?". That generated
<B xsi:nil="true" xmlns=""/>
Web service pukes on that.
tweaked the proxy to be string (!). With a null value of the string, the property dropped out of the generated XML all together. Web service pukes on that.
Set the value of the string to " " (space). Xml generates as
<B> </B>
Web service Happy. Developer Sad.
Am I missing something? Is there some magic wand I can wave during WSDL import that makes this work? Some configuration I can set on my proxy? I don't think there is, but I want to do the due diligence to make sure I'm not missing anything before I escalate further.
My workaround incredibly kludgy imo. The real problem with it is, if I can't trust the contracts (of which there are MANY I have to integrate with), all of my development estimates just went out the window. This first integration should have been a few minutes work. Import wsdl. Set property values. Call method. Instead it was 2 hours of tweaking the code repeatedly , capturing the payload in Fiddler, and running tests manually in SoapUI to figure out what was being sent, and what the service actually demanded.
In this particular use case of this method, the string kludge works. But in if a requirement down the road requires me to actually send that parameter, now I have a property that I think is a string, that is actually an integer. (I suppose I could wrap the string field in a second integer parameter, but that's more kludge)
On top of that, the 3rd party has been changing the WSDL as their development process continues, (which is expected for this project), but every time they add a property or something, I have to re-import the WSDL, which means all my manual tweaks need to be redone.
Help?

CXF web service issue when using #WebParam (header=true)

I need help here. I have at work a CXF web service working really well running in a WebLogic server. I recently was asked to pass some extra parameters (for extra authentication purposes). We want these extra parameters to travel in the header, not as normal parameters.
I have two different scenarios to explain. In fact, in scenario number 1, everything works really well, I am very please with it as my web service received the header parameters and I can validate them. But then, in scenario number 2, in running time, all these new parameters in the header are NULL (and normal parameters are correctly populated!). So I cannot validate the header ones. And I need scenario 2 to work as we want these extra parameters to be in the header.
Why this binding is not working in my second scenario ? there is a bug ? Am I missing something ? Please help me. Here I describe both scenarios with some code for clarification:
1) Here everything works fine. In my cxf-servlet.xml file I have the endpoint defined as:
<jaxws:endpoint id="omniWebService"
implementor="server.com.omnipay.webservice.webService.ServiceImpl"
address="/omniWS" />
And one of the calls that my CXF web service interface is offering is for instance this one where you can see that the 3 first parameters are header=true, not the others.
#WebResult (name="merchantHierarchyParentResponse") MerchantHierarchyParentResponseDTO
getParent(
#WebParam(header=true, name="callerId") String callerId,
#WebParam(header=true, name="timestamp") String timestamp,
#WebParam(header=true, name="signature") String signature,
#WebParam(name="institutionNumber") #XmlElement(required=true) String institutionNumber,
#WebParam(name="clientNumber") String clientNumber,
#WebParam(name="ourReference") String ourReference,
#WebParam(name="accessMerch") String accessMerch
);
That's all. I don't think I need to show more. This is working fine. I deploy in WebLogic and my client or soapUI or debugging or whatever I do, the web service receives all these parameters and I can work with them.
2) The real endpoint I want to use in my cxf-servlet.xml is the following:
<jaxws:endpoint id="omniWebService"
implementor="server.com.omnipay.webservice.webService.ServiceImpl"
address="/omniWS" wsdlLocation="WEB-INF/omniWebService.wsdl">
<jaxws:properties>
<entry key="schema-validation-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>
And the reason to use this one is because I need a "local" WSDL that I can edit and make changes. This "local" WSDL is the exact WSDL that WebLogic provided me after my first deployment plus adding things like this plus using them instead of type="xs:string":
<!-- Institution Number is a required 8 numeric positions IN parameter -->
<xs:simpleType name="institutionNumber">
<xs:restriction base="xs:string">
<xs:length value="8"/>
<xs:pattern value="[0-9]+"/>
</xs:restriction>
</xs:simpleType>
This is, adding some restrictions so the WSDL will validate the user input. For instance 00000123 is a valid institution number but 000000XX is not.
This functionality works really nice. To be honest, it forces me to maintain a "local" WSDL file which I would prefer not but I didn't find any other way to do it.
And here is where I have my problem. Even if I put as "local" WSDL the exact content of the "automatic" WSDL that WebLogic provided me after deploying (the original without any of my changes!), the result is that in execution time my normal parameters (institution number, client number, etc) are correctly populated but my 3 header parameters (callerId, timestamps and signature) are NULL.
Please any suggestion ? what I am doing wrong ? Both functionalities works very nicely when not working together but the moment I put them together I am having this problem in execution. Why the binding is working fine in scenario 1 but not in scenario 2 ?
thanks
I found the problem. Well, I tried something mad and it works. I put the 3 header parameters at the end, and then it works ! I find this very strange. Why can't I put them on the beginning ? Is it maybe a WebLogic problem ? Am I using old CXF classes with a bug ? Very strange but happy it is fixed now !
#WebResult (name="merchantHierarchyParentResponse") MerchantHierarchyParentResponseDTO
getParent(
#WebParam(name="institutionNumber") #XmlElement(required=true) String institutionNumber,
#WebParam(name="clientNumber") String clientNumber,
#WebParam(name="ourReference") String ourReference,
#WebParam(name="accessMerch") String accessMerch,
#WebParam(header=true, name="callerId") String callerId,
#WebParam(header=true, name="timestamp") String timestamp,
#WebParam(header=true, name="signature") String signature
);

How to specify both jaxws and jaxb bindings to achieve #XmlRootElement

I've inherited a project that communicates with a SOAP-based web service. I'm a total noob at this, although have been doing Java for many years and have done a good bit with XML.
We have a WSDL file for the service, which contains the schema at the top and all the message definition stuff below. At the core of the problem, when I try to connect to the service through our code, I get the dreaded unable to marshal type "https.api_blah_com.services.v4.Product" as an element because it is missing an #XmlRootElement annotation]
My project already has a jaxws binding file:
<jaxws:bindings wsdlLocation="../resources/wsdl/BlahAPI.wsdl"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
<jaxws:bindings
node="wsdl:definitions/wsdl:types/xs:schema[#targetNamespace='https:api.blah.com/services/v4']">
<jxb:globalBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xjc:generateElementProperty>true</xjc:generateElementProperty>
</jxb:globalBindings>`
</jaxws:bindings>
</jaxws:bindings>
Now I've read that in order to get all my Java classes generated with #XmlRootElement, I need to add a jaxb:globalBinding turning on simple mode.
I've tried adding to my local copy of the WSDL this:
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<xjc:simple />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
But the JAXB compiler complains that it cannot honor this globalBindings customization because it's attached to a wrong place or is inconsistent with other bindings.
So I tried adding another bindings file, just for jaxb, like so:
<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:bindings schemaLocation="../resources/wsdl/blah.wsdl">
<jaxb:globalBindings>
<xjc:simple />
</jaxb:globalBindings>
</jaxb:bindings>
</jaxb:bindings>
But then I get an error that blah.wsdl is not part of this compilation.
I am so close to calling this service...I just cannot get past this one thing, and it's all new to me so I'm not sure what else to try.
I could split out their WSDL into an XSD and a WSDL? Is that required to make this work?
I think you have to bind the xsd file not wsdl at this location. <jaxb:bindings schemaLocation="../resources/wsdl/blah.wsdl">. Please refer to section "External Binding Customization Files" at link.
Not sure if JAXB Binding is configured correctly. The #XmlRootElement required if class forms the root of your element structure. However in SOAP, SOAP element would form root of the XML, Hence check if your ObjectFacory.java class is generated, if generated verify if a method is created for the class type which returns an instance of the class type for example you have class Foo an method `public Foo createFoo() which returns instance of Foo should be present in your ObjectFoacory.java
However I would suggest you to use CXF provided WSDL2java this with client option enabled. It takes few minutes to configure a client code

coldfusion and wsdl datatypes

I am trying to use a wsdl with cold fusion 9, but every time I try to make I try to call a function, I get an AxisFault Internal Server Error. I think the error is from the wsdl wanting data type's and cold fusion not casting them properly, like "dateTime" or things like
<xs:element name="MaximumNumberOfMatches" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:positiveInteger">
<xs:maxInclusive value="10"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
Is there a hack to get around this, as it seems using javaCast isn't getting the job done.
For passing the dateTime, I found this code to work
myJavaDate = CreateObject("java", "java.util.GregorianCalendar").getInstance();
myJavaDate.setTimeInMillis(0);
I remember running into trouble with PositiveInteger's back in CF8. Things may have changed in CF9, but back then creating an instance of that class was the only thing that seemed to do the trick:
num = createObject("java", "org.apache.axis.types.PositiveInteger").init(123);
First thing I would do is a trim of your xml. Often times a leading space can cause the problem.
<cfhttp method = "get"...>
<cfset myXML = trim(cfhttp.FileContent)>
Are you the owner of this service or is it out of your control? The only time i've gotten this error was when there was a problem creating the wsdl output. Server configuration changed and the cfc bombed.
HTH
P.S. the actual error would be a help.

gSOAP and general SOAP problem

I am using gSOAP to create C++ code from a WSDL document. The problem is gSOAP is giving me errors when I run the wsdl2h tool on my WSDL file. The errors are all related to namespace issues. For example
Warning: could not find element 'GetRPCMethods' type '"http://www.broadband-forum.org/cwmp/cwmp-1-2.xsd":GetRPCMethods' in schema urn:tr069
I have pasted the namespace definitions and an example of how they are used below. Anyone know where I am going wrong?
urn:tr069 is supposed to refer to the current document.
<s0:definitions
name="tr069"
xmlns:s0="http://schemas.xmlsoap.org/wsdl/"
xmlns:s1="urn:tr069"
xmlns:s2="http://schemas.xmlsoap.org/wsdl/soap/"
targetNamespace="urn:tr069">
<s0:types>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="urn:tr069"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd1="http://www.broadband-forum.org/cwmp/cwmp-1-2.xsd"
targetNamespace="urn:tr069">
<xsd:import namespace="urn:dslforum-org:cwmp-1-2" schemaLocation="cwmp-1-2.xsd" />
<xsd:element name="GetRPCMethods" type="xsd1:GetRPCMethods" />
</xsd:schema>
</s0:types>
<s0:message name="GetRPCMethods">
<s0:part element="s1:GetRPCMethods" name="GetRPCMethods" />
</s0:message>
</s0:definitions>
I have a few other questions, as I understand it the target namespace does not have to point to a real location, it is just a convention for pointing to the current document, Is this correct? Also in cwmp-1-2.xsd there is an element called GetRPCMethods which contains a sequence containing another element. Is it best practice to use this whole element(GetRPCMethods) as a part for a message as I have above or should I define the specific parts of GetRPCMethods in the message?
Thank you.
The problem was the elements defined in the <schema> tag. First I removed all the defined elements inside the <schema> tag because they were completely unnecessary anyway. Then I changed the namespace of the elements in the message parts from s1 to xsd1 to use the elements in cwmp-1-2.xsd instead of the ones I defined in the <schema> tag.
As for my other questions, the targetNameSpace does not have to point to a real uri, it is just a name for the namespace of this document. For my second question, I think it is probably best and easiest to use the whole schema element as the part for the message.
I notice that
<xsd:schema>
doesn't have a closing tag? Is the wsdl a well-formed XML Document?
Targetnamespace is the namespace of the instance document ie., the one for SOAP:Envelope.
The error message says what's wrong, you don't have a definition of xsd1:GetRPCMethods, is this somewhere defined?
s1:GetRPCMethods is looked up -> s1 is found to be urn:trn069 -> urn:trn069 is not unique which might be a problem -> urn:trn69 defines the element, GetRPCMethods which is of type xsd1:GetRPCMethods -> this type is not found.
I'm not sure if it is valid to use the same URI for the targetNamespace. Maybe that's causing additional problems.