Issues

ZF-6077: Zend Soap Wsdl Strategy ArrayOfComplexType fails to generate JAX importable descriptions

Description

Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex makes use of soap enc array currently unsupported by many if not all JAX tools. I currently solved this by modifying Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex; instead I use a sequence of objects, so I changed from:


            $complexType = $dom->createElement('xsd:complexType');
            $complexType->setAttribute('name', $xsdComplexTypeName);

            $complexContent = $dom->createElement("xsd:complexContent");
            $complexType->appendChild($complexContent);

            $xsdRestriction = $dom->createElement("xsd:restriction");
            $xsdRestriction->setAttribute('base', 'soap-enc:Array');
            $complexContent->appendChild($xsdRestriction);

            $xsdAttribute = $dom->createElement("xsd:attribute");
            $xsdAttribute->setAttribute("ref", "soap-enc:arrayType");
            $xsdAttribute->setAttribute("wsdl:arrayType", sprintf("tns:%s[]", $singularType));
            $xsdRestriction->appendChild($xsdAttribute);

            $this->getContext()->getSchema()->appendChild($complexType);
            $this->getContext()->addType($xsdComplexTypeName);

to


            $complexType = $dom->createElement('xsd:complexType');
            $complexType->setAttribute('name', sprintf('%s',$xsdComplexTypeName));

            $complexContent = $dom->createElement("xsd:sequence");
            $complexType->appendChild($complexContent);

            $xsdRestriction = $dom->createElement("xsd:element");
            $xsdRestriction->setAttribute('name', $singularType);
            $xsdRestriction->setAttribute('type', sprintf('tns:%s',$singularType));
            $xsdRestriction->setAttribute('minOccurs','0');
            $xsdRestriction->setAttribute('maxOccurs','unbounded');
            $complexContent->appendChild($xsdRestriction);

            $this->getContext()->getSchema()->appendChild($complexType);
            $this->getContext()->addType($xsdComplexTypeName);

So the generated wsdl changes from:


                        

to:


                        

Works for me and can be imported using JAX wsimport

Comments

Two weeks ago Benjamin and I talked about exactly this way how to solve the problem with other clients than php's SoapClient. I'll take a look at it to check if my problems will be solved by changing the code like mentioned.

@Erick: seems to work fine. i've sent Benjamin my test environment in hope he can test it :-) didn't you need to add the "namespace"-attribute to ? my wsimport cannot create java sources/binaries without having this attribute.

@Benjamin: do we now need junit tests? we should check if we need the "namespace"-attribute for all elements.

h2. Stable (using Zend_Soap_Wsdl_Strategy_ArrayOfTypeComplex)

h3. Java [automated class generation]

# wsimport -keep -verbose http://zend.flabben.net/service.php?stable
parsing WSDL...


[WARNING] src-resolve.4.2: Error resolving component 'soap-enc:Array'. It was detected that 'soap-enc:Array' is in
namespace 'http://schemas.xmlsoap.org/soap/encoding/', but components from this namespace are not referenceable
from schema document 'http://zend.flabben.net/service.php/?stable…'. If this is the incorrect namespace,
perhaps the prefix of 'soap-enc:Array' needs to be changed. If this is the correct namespace, then an appropriate
'import' tag should be added to 'http://zend.flabben.net/service.php/?stable…'.  line 2 of
http://zend.flabben.net/service.php/?stable…

[ERROR] undefined simple or complex type 'soap-enc:Array'
  line 2 of http://zend.flabben.net/service.php?stable

[ERROR] undefined attribute 'soap-enc:arrayType'
  line 2 of http://zend.flabben.net/service.php?stable

Exception in thread "main" java.lang.NullPointerException
        at com.sun.tools.internal.xjc.reader.internalizer.SCDBasedBindingSet.apply(SCDBasedBindingSet.java:201)
        at com.sun.tools.internal.xjc.ModelLoader.createXSOM(ModelLoader.java:502)
        at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:216)
        at com.sun.tools.internal.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:69)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.JAXBModelBuilder.bind(JAXBModelBuilder.java:120)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildJAXBModel(WSDLModeler.java:2173)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.internalBuildModel(WSDLModeler.java:173)
        at com.sun.tools.internal.ws.processor.modeler.wsdl.WSDLModeler.buildModel(WSDLModeler.java:119)
        at com.sun.tools.internal.ws.wscompile.WsimportTool.run(WsimportTool.java:170)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.tools.internal.ws.Invoker.invoke(Invoker.java:100)
        at com.sun.tools.internal.ws.WsImport.main(WsImport.java:38)

h3. Python (ZSI)

from ZSI import ServiceProxy
fp = open('logfile.dat', 'a')
proxy = ServiceProxy.ServiceProxy('http://zend.flabben.net/service.php?unstable')
print proxy.getDynamicString('hallo')
fp.close()
C:\Server\workspace\Zoap>python client.py
C:\Server\python\lib\site-packages\ZSI\resolvers.py:7: DeprecationWarning: the multifile module has been deprecated since Python 2.5
  import multifile, mimetools, urllib
C:\Server\python\lib\site-packages\ZSI\wstools\XMLSchema.py:3072: DeprecationWarning: object.__init__() takes no parameters
  tuple.__init__(self, args)
Traceback (most recent call last):
  File "client.py", line 3, in 
    proxy = ServiceProxy.ServiceProxy('http://zend.flabben.net/service.php?stable')
  File "C:\Server\python\lib\site-packages\ZSI\ServiceProxy.py", line 100, in __init__
    commands.wsdl2py(['-u', wsdl,'-o', cachedir, '-t', types])
  File "C:\Server\python\lib\site-packages\ZSI\generate\commands.py", line 223, in wsdl2py
    wsm.writeClient(fd)
  File "C:\Server\python\lib\site-packages\ZSI\generate\wsdl2python.py", line 212, in writeClient
    sd.write(fd,msg_fd)
  File "C:\Server\python\lib\site-packages\ZSI\generate\wsdl2python.py", line 319, in write
    print >>fd, m
  File "C:\Server\python\lib\site-packages\ZSI\generate\wsdl2python.py", line 340, in __str__
    return self.content.getvalue()
  File "C:\Server\python\lib\site-packages\ZSI\generate\containers.py", line 272, in getvalue
    self._setContent()
  File "C:\Server\python\lib\site-packages\ZSI\generate\containers.py", line 999, in _setContent
    raise WSInteropError, WSISpec.R2717
ZSI.generate.WSInteropError: An rpc-literal binding in a DESCRIPTION MUST have the namespace attribute specified, the value of which MUST be
 an absolute URI, on contained  soapbind:body elements.

h2. Unstable (using Zoap_Wsdl_Strategy_ArrayOfTypeComplex)

h3. Java [automated class generation]

# wsimport -keep -verbose http://zend.flabben.net/service.php?unstable
parsing WSDL...


generating code...
net\flabben\zend\service\ArrayOfZoapServiceResult.java
net\flabben\zend\service\ObjectFactory.java
net\flabben\zend\service\ZoapServicePort.java
net\flabben\zend\service\ZoapServiceResult.java
net\flabben\zend\service\ZoapServiceService.java
net\flabben\zend\service\package-info.java

h3. Java [call all methods]

package net.flabben.zend.client;
import net.flabben.zend.service.*;

// wsimport -keep 

public class ZoapClient
{
    /**
     * @param args
     */
    public static void main(String[] args)
    {
        String result = new ZoapServiceService().getZoapServicePort().getStaticString();
        if (result != null) {
            System.out.println("Result: " + result);
        } else {
            System.out.println("Result is NULL");
        }

        result = new ZoapServiceService().getZoapServicePort().getDynamicString("Test");
        if (result != null) {
            System.out.println("Result: " + result);
        } else {
            System.out.println("Result is NULL");
        }

        result = new ZoapServiceService().getZoapServicePort().getFrameworkVersion();
        if (result != null) {
            System.out.println("Result: " + result);
        } else {
            System.out.println("Result is NULL");
        }

        ArrayOfZoapServiceResult array =new ZoapServiceService().getZoapServicePort().getArray();
        if (array != null) {
            System.out.println("Result: " + array);
        } else {
            System.out.println("Result is NULL");
        }
    }
}
Result: Hello world!
Result: Test
Result: 1.8.0alpha
Result: net.flabben.zend.service.ArrayOfZoapServiceResult@ca470

h3. Python (ZSI)

C:\Server\workspace\Zoap>python client.py
C:\Server\python\lib\site-packages\ZSI\resolvers.py:7: DeprecationWarning: the multifile module has been deprecated since Python 2.5
  import multifile, mimetools, urllib
C:\Server\python\lib\site-packages\ZSI\wstools\XMLSchema.py:3072: DeprecationWarning: object.__init__() takes no parameters
  tuple.__init__(self, args)
Traceback (most recent call last):
  File "client.py", line 4, in 
    print proxy.getDynamicString('hello')
  File "C:\Server\python\lib\site-packages\ZSI\ServiceProxy.py", line 413, in __call__
    return self.parent()._call(self.__name__, *args, **kwargs)
  File "C:\Server\python\lib\site-packages\ZSI\ServiceProxy.py", line 193, in _call
    encodingStyle=callinfo.encodingStyle)
  File "C:\Server\python\lib\site-packages\ZSI\client.py", line 226, in Send
    sw.serialize(obj, requesttypecode)
  File "C:\Server\python\lib\site-packages\ZSI\writer.py", line 117, in serialize
    elt = typecode.serialize(self.body, self, pyobj, **kw)
  File "C:\Server\python\lib\site-packages\ZSI\TCcompound.py", line 273, in serialize
    self.cb(elt, sw, pyobj, name=name, **kw)
  File "C:\Server\python\lib\site-packages\ZSI\TCcompound.py", line 348, in cb
    raise TypeError("Classless struct didn't get dictionary")
TypeError: Classless struct didn't get dictionary

h2. Resources

http://zend.flabben.net/service.php?stable http://zend.flabben.net/service.php?unstable http://zend.flabben.net/sources/service.phps http://zend.flabben.net/sources/Zoap_Service.phps http://zend.flabben.net/sources/… http://zend.flabben.net/sources/…

Jan: I'm not sure but I think I grabbed a version of Zend_Soap_Autodiscover from SVN trunk that can set namespace as you say. I'll check this later. About the wsimport you posted, which version of Zoap_Wsdl_Strategy_ArrayOfTypeComplex are you using? did you add namespace attribute?

Is the problem that Zend_Soap_Wsdl_Strategy_ArrayOfTypeSequence does not support complex types?

I guess the whole fun of strategies was to fix these problems to their specific kinds.

Does this issue go if ArrayOfTypeSequence supports complex types as suggested in ZF-6742? Would this patch fix your problem?

I am trying to implement this fix it is needed for our workflow engine to work since it uses JAX. I have made the code change from above and still no luck. I am running latest version of ZF.