Apache Axis: no containing element
Asked Answered
B

2

6

I received the following WSDL from a vendor. The sample service behind it runs on Microsoft .NET. I need to create a web service in Java based on this WSDL.

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" 
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
xmlns:tns="http://www.somecompany.com/" 
xmlns:s="http://www.w3.org/2001/XMLSchema" 
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
targetNamespace="http://www.somecompany.com/" 
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://www.somecompany.com/">
    <s:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="http://www.w3.org/2001/XMLSchema.xsd" />
      <s:element name="getInventoryStatus">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="DealerCode" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="SupplierCode" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="PartNumber" type="s:string" />
            <s:element minOccurs="1" maxOccurs="1" name="Quantity" type="s:int" />
            <s:element minOccurs="0" maxOccurs="1" name="DeliveryLocation" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="getInventoryStatusResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="getInventoryStatusResult">
              <s:complexType>
                <s:sequence>
                  <s:element ref="s:schema" />
                  <s:any />
                </s:sequence>
              </s:complexType>
            </s:element>
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:schema>
  </wsdl:types>
  <wsdl:message name="getInventoryStatusSoapIn">
    <wsdl:part name="parameters" element="tns:getInventoryStatus" />
  </wsdl:message>
  <wsdl:message name="getInventoryStatusSoapOut">
    <wsdl:part name="parameters" element="tns:getInventoryStatusResponse" />
  </wsdl:message>
  <wsdl:portType name="InventoryInquirySoap">
    <wsdl:operation name="getInventoryStatus">
      <wsdl:input message="tns:getInventoryStatusSoapIn" />
      <wsdl:output message="tns:getInventoryStatusSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="InventoryInquirySoap" type="tns:InventoryInquirySoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getInventoryStatus">
      <soap:operation soapAction="http://www.somecompany.com/getInventoryStatus" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="InventoryInquiry">
    <wsdl:port name="InventoryInquirySoap" binding="tns:InventoryInquirySoap">
      <soap:address location="http://www.somecompany.com/InventoryInquiry.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

I modified the WSDL I received to include the following line so that Eclipse would recognize the WSDL as valid:

<s:import namespace="http://www.w3.org/2001/XMLSchema" schemaLocation="http://www.w3.org/2001/XMLSchema.xsd" />  <!--  added for Eclipse-->

I've included this WSDL file in a new Dynamic Web Project. I used the New Web Service wizard to create a new top down web service based on the WSDL.

When I deploy the project to Tomcat and call the web service, Apache Axis reports back the following:

AXIS error

Sorry, something seems to have gone wrong... here are the details:

Fault - makeTypeElement() was told to create a type "{http://www.somecompany.com/}>>getInventoryStatusResponse>getInventoryStatusResult", with no containing element

AxisFault faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.generalException faultSubcode: faultString: makeTypeElement() was told to create a type "{http://www.somecompany.com/}>>getInventoryStatusResponse>getInventoryStatusResult", with no containing element faultActor: faultNode: faultDetail: {http://xml.apache.org/axis/}hostname:HOME-DELL

The demo web service provided by the vendor returns the following:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <soap:Body>
      <GetInventoryStatusResponse xmlns="http://ctire.aktion.com/">
         <GetInventoryStatusResult>
            <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
               <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                  <xs:complexType>
                     <xs:choice minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="InventoryStatus">
                           <xs:complexType>
                              <xs:sequence>
                                 <xs:element name="InStock" type="xs:int" minOccurs="0"/>
                                 <xs:element name="EstDeliveryDate" type="xs:string" minOccurs="0"/>
                                 <xs:element name="EstDeliveryTime" type="xs:string" minOccurs="0"/>
                                 <xs:element name="DeliveryLocation" type="xs:string" minOccurs="0"/>
                              </xs:sequence>
                           </xs:complexType>
                        </xs:element>
                     </xs:choice>
                  </xs:complexType>
               </xs:element>
            </xs:schema>
            <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
               <NewDataSet xmlns="">
                  <InventoryStatus diffgr:id="InventoryStatus1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
                     <InStock>36</InStock>
                     <EstDeliveryDate>09/27/2016</EstDeliveryDate>
                     <EstDeliveryTime>12:00 PM</EstDeliveryTime>
                     <DeliveryLocation>883620750</DeliveryLocation>
                  </InventoryStatus>
               </NewDataSet>
            </diffgr:diffgram>
         </GetInventoryStatusResult>
      </GetInventoryStatusResponse>
   </soap:Body>
</soap:Envelope>

I think I need to reference a schema for the NewDataSet in the WSDL, but I'm not sure how to do that.

Bedchamber answered 26/9, 2016 at 11:35 Comment(0)
H
0

Do you know soapUI? You can import your WSDL and make some requests against the demo service. Just to check that your infrastructure works properly.

If everything seems to work, try this: Have Java generate the classes from the WSDL via the "wsimport" command like this:

%JAVA_HOME%/bin/wsimport -d [RELATIVE_PATH_FOR_GENERATED_CLASSES] -encoding UTF-8 -keep -verbose [RELATIVE_PATH_OF_YOUR_WSDL]

In your code try to use these generated classes and deploy again.

You can get the full documentation of wsimport from here

Hope that helps in any way.

Honest answered 11/10, 2016 at 10:11 Comment(4)
What's the difference between wsimport and using Axis, which is included with Eclipse?Bedchamber
Yes, I know soapUI. As noted in the question, the issue is that I can't access the service that Axis builds, due to an issue with Axis conversion of the WSDL to Java classes.Bedchamber
Have you tried to generate the artifacts via wsimport? This tool has served me well more than once. Other tools' outcome - I can't remember which I tried but I think AXIS was one of them - didn't work.Honest
Maybe this link is useful for you: #4627740Honest
I
0

It's recommended to use JAX-WS, which is a Java Standard. It cooperates easily with JAXB, which is also needed here.

In this case, the server has a dynamic response which includes an schema definition and a free object, but it seems that is an diffgram node (from a Microsoft XSD) and an object instance that complies with the previous XSD definition and some diffgram attributes.

This solution ignores the diffgram node (but not it's contents) because i don't have the appropiate XSD from Microsoft (it's supposed to be in "msdata.xsd from Visual Studio %InstallRoot%\Xml\Schemas directory). It's only a matter of putting the right XSD and following the steps.

Steps to create the service:

  • Download http://www.apache.org/dyn/closer.lua/cxf/2.7.18/apache-cxf-2.7.18.zip
  • In Eclipse -> Window -> Preferences -> CXF -> Add and then select + apply
  • Create a Dynamic Web Project and put the WSDL in src
  • Web Services -> Generate Java Skeleton -> Runtime CXF -> Finish
  • Put in the schema definition from the sample response in diffgram-v1.xsd

  • Generate JAXB classes in a command line with "xjc diffgram-v1.xsd" (from java bin classpath)

  • Change GetInventoryStatusResponse.GetInventoryStatusResult adding before class definition "@XmlSeeAlso({NewDataSet.class})" to support returning this object via JABX in the service
  • Implement InventoryInquirySoapImpl.getInventoryStatus returning the XSD parsed and an instance of NewDataSet:

        InventoryStatus ie = new InventoryStatus();
        ie.setDeliveryLocation("del");
        ie.setInStock(36);
        ie.setEstDeliveryDate("09/27/2016");
        ie.setDeliveryLocation("883620750");
    
        NewDataSet nds = new NewDataSet();
        nds.getInventoryStatus().add(ie);
    
        GetInventoryStatusResponse.GetInventoryStatusResult _return = new GetInventoryStatusResponse.GetInventoryStatusResult();
    
        _return.setSchema(parseDiffgramSchema());
        _return.setAny(nds);
        return _return;
    
  • parseDiffgramSchema can be implemented with JABX:

    // TODO cache
    URL file = this.getClass().getClassLoader()
            .getResource("diffgram-v1.xsd");
    
    JAXBContext jaxbContext = JAXBContext.newInstance(Schema.class);
    
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    
    Schema schema = (Schema) jaxbUnmarshaller.unmarshal(file);
    
    return schema;
    

Full example in my GIT https://github.com/sergio-otero/TestJAXWS/tree/master/TestJAXWS

Ia answered 11/10, 2016 at 16:27 Comment(5)
I'm using Axis to create the web service from the WSDL, not to create a client to invoke the existing service.Bedchamber
Ok. I have an example returning the "xs:schema" part but not the "diffgram" part. I'll be easier if you can provide msdata.xsd from Visual Studio %InstallRoot%\Xml\Schemas directoryIa
The actual .NET web service is from a vendor. I've asked them for that schema.Bedchamber
Changed solution from generating client to publishing server, but without the full XSD from MicrosoftIa
I'm going to give you the reward because you definitely made an effort to help me with this. Unfortunately, I have a rush project to tackle and won't be able to look at this until next week or so. I'll add comments here in case I get stuck. Thanks!Bedchamber

© 2022 - 2024 — McMap. All rights reserved.