Bugs are submitted. Patches are created, tested, and license granted on:
rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
(revision 1158970)
I checked out the 2.4.1 tag from SVN and patched on that since I am testing on
2.4.1. I tested by running "mvn -Pfastinstall install" in the
rt/frontend/jaxws directory. For some reason, I cannot compile the whole CXF,
so I just stitched the class files created in jaxws back into the cxf-2.4.1.jar
and tested that way. I always get the following build error in the top level
directory if I run that mvn command:
[INFO] Registering compile source root
/home/jpangburn/open_source/apache-cxf-2.4.1/cxfsvn/testutils/target/generated/src/main/java
[INFO] [cxf-xml2fastinfoset:xml2fastinfoset {execution: xml2fastinfoset}]
[INFO] [cxf-codegen:wsdl2java {execution: generate-sources}]
[INFO] Running wsdl2java in fork mode...
[INFO] Building jar: /tmp/cxf-tmp-855110/cxf-codegen4741067092732935059.jar
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO]
Exit code: 1 - Exception in thread "main"
org.apache.cxf.tools.common.ToolException: Thrown by JAXB:
cvc-complex-type.3.2.2: Attribute 'xjc:recursive' is not allowed to appear in
element 'class'. at line 44 column 28 of schema
jar:file:/home/jpangburn/open_source/apache-cxf-2.4.1/cxfsvn/tools/wsdlto/databinding/jaxb/target/cxf-tools-wsdlto-databinding-jaxb-2.4.1.jar!/org/apache/cxf/tools/wsdlto/databinding/jaxb/W3CEPRJaxbBinding_jaxb22.xml
at
org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBBindErrorListener.error(JAXBBindErrorListener.java:35)
at
com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.error(SchemaCompilerImpl.java:286)
at
com.sun.tools.xjc.util.ErrorReceiverFilter.error(ErrorReceiverFilter.java:77)
at
com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:134)
at
com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
at
com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator$XSIErrorReporter.reportError(XMLSchemaValidator.java:417)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.reportSchemaError(XMLSchemaValidator.java:3181)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.processAttributes(XMLSchemaValidator.java:2658)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:2065)
at
com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
at
com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:549)
at
com.sun.tools.xjc.util.ForkContentHandler.startElement(ForkContentHandler.java:110)
at
org.xml.sax.helpers.XMLFilterImpl.startElement(XMLFilterImpl.java:527)
at
com.sun.tools.xjc.reader.internalizer.DOMForestScanner$LocationResolver.startElement(DOMForestScanner.java:141)
at com.sun.xml.bind.unmarshaller.DOMScanner.visit(DOMScanner.java:239)
at com.sun.xml.bind.unmarshaller.DOMScanner.scan(DOMScanner.java:122)
at
com.sun.tools.xjc.reader.internalizer.DOMForestScanner.scan(DOMForestScanner.java:89)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet$Target.apply(SCDBasedBindingSet.java:180)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet$Target.applyAll(SCDBasedBindingSet.java:138)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet$Target.apply(SCDBasedBindingSet.java:159)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet$Target.applyAll(SCDBasedBindingSet.java:138)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet$Target.access$700(SCDBasedBindingSet.java:82)
at
com.sun.tools.xjc.reader.internalizer.SCDBasedBindingSet.apply(SCDBasedBindingSet.java:237)
at com.sun.tools.xjc.ModelLoader.createXSOM(ModelLoader.java:522)
at
com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:236)
at
com.sun.tools.xjc.api.impl.s2j.SchemaCompilerImpl.bind(SchemaCompilerImpl.java:85)
at
org.apache.cxf.tools.wsdlto.databinding.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:393)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.generateTypes(WSDLToJavaContainer.java:588)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.processWsdl(WSDLToJavaContainer.java:240)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:138)
at
org.apache.cxf.tools.wsdlto.WSDLToJavaContainer.execute(WSDLToJavaContainer.java:283)
at
org.apache.cxf.tools.common.toolspec.ToolRunner.runTool(ToolRunner.java:103)
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.maven_plugin.ForkOnceWSDL2Java.main(ForkOnceWSDL2Java.java:50)
Caused by: org.xml.sax.SAXParseException: cvc-complex-type.3.2.2: Attribute
'xjc:recursive' is not allowed to appear in element 'class'.
at
com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at
com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
... 32 more
Command line was: /usr/java/jdk1.6.0_21/jre/bin/java -jar
/tmp/cxf-tmp-855110/cxf-codegen4741067092732935059.jar
/tmp/cxf-tmp-855110/cxf-w2j2524062641163889042args
I'm running java 1.6.0_21 and maven 2.2.1. If you have any idea what's wrong
here I can test the patches with a real build, otherwise I think it's fine the
way it is- if somewhat inconvenient.
Thanks,
Jesse
-----Original Message-----
From: Daniel Kulp [mailto:[email protected]]
Sent: Wednesday, August 17, 2011 2:28 PM
To: [email protected]
Cc: Jesse Pangburn
Subject: Re: dispatch api with ws-addressing
They both look like bugs to me. Log some issues and patches are ALWAYS
welcome. :-)
Dan
On Wednesday, August 17, 2011 4:19:13 PM Jesse Pangburn wrote:
> Hi,
> I found the cause of the problem to be a bug in this method in CXF (I have
> version 2.4.1): private Map<String, QName>
> createPayloadEleOpNameMap(BindingInfo bindingInfo) { Map<String, QName>
> payloadElementMap = new java.util.HashMap<String, QName>(); for
> (BindingOperationInfo bop : bindingInfo.getOperations()) {
> SoapOperationInfo soi =
> (SoapOperationInfo)bop.getExtensor(SoapOperationInfo.class); if (soi !=
> null) {
> if ("document".equals(soi.getStyle())) {
> // if doc
> if (bop.getOperationInfo().getInput() != null
> &&
> !bop.getOperationInfo().getInput().getMessageParts().isEmpty()) { QName qn
> = bop.getOperationInfo().getInput().getMessagePartByIndex(0)
> .getElementQName();
> payloadElementMap.put(qn.toString(),
> bop.getOperationInfo().getName()); }
> } else if ("rpc".equals(soi.getStyle())) {
> // if rpc
>
> payloadElementMap.put(bop.getOperationInfo().getName().toString(),
> bop.getOperationInfo() .getName());
> }
> }
> }
> return payloadElementMap;
> }
>
> The problem is that it requires the SoapOperationInfo to have a style
> attribute, but in the W3C spec for WSDL it says the style attribute on the
> soap operation is optional, specifically ' If the attribute is not
> specified, it defaults to the value specified in the soap:binding element.
> If the soap:binding element does not specify a style, it is assumed to be
> "document".' So the code needs to check if the soi has a style and if not
> read it from the binding and if not then set it as "document". This is not
> a problem in the WSDLs generated by CXF (as I found out with a HelloWorld
> test) because it creates these optional style attributes, but since W3C
> says people can generate WSDLs without these (and I ran into one) I think
> it's worth fixing.
>
> Unless someone disagrees, I'll create a defect for this and contribute a
> patch.
>
> While reading code and stepping through the debugger to find out where this
> was going wrong, I also found that if you use a SOAPMessage instead of a
> Source then the following function fails (ignoring the exception) and your
> ws-addressing action doesn't get set either- if you have any whitespace
> after the soap:body element before your first payload element: private
> String getPayloadElementName(SOAPMessage soapMessage) { try {
> SOAPElement element =
> (SOAPElement)soapMessage.getSOAPBody().getChildElements().next(); return
> new QName(element.getNamespaceURI(), element.getLocalName()).toString(); }
> catch (Exception e) {
> //ignore
> }
> return null;
>
> }
>
> This fails because the .next() call at the end gets a text node instead of
> an element object so the cast fails. So inexplicably your ws-addressing
> action header doesn't get set in this case either. Unless someone
> disagrees, I'll create a defect for this as well and contribute a patch.
>
> Thanks so much for your help! I wouldn't have gone looking and found this
> out without knowing it *should* work.
>
> Jesse
>
> -----Original Message-----
> From: Jesse Pangburn
> Sent: Wednesday, August 17, 2011 11:17 AM
> To: 'Daniel Kulp'; [email protected]
> Subject: RE: dispatch api with ws-addressing
>
> Hi Dan,
> Thanks for the suggestion, I'm trying to figure out one of those cases. I
> changed the code to this to try a DOMSource instead: Dispatch<Source> disp
> = service.createDispatch(new QName("urn:ihe:iti:xds-b:2007",
> "DocumentRegistry_Port_Soap12"), Source.class, Service.Mode.PAYLOAD, new
> AddressingFeature()); InputStream is =
> IBServer.class.getResourceAsStream("RegistryQuery.xml"); Document doc =
> XMLUtils.parse(is);
> DOMSource reqMsg = new DOMSource(doc);
> Source response = disp.invoke(reqMsg);
>
> DOMSource also sent the same wrong action header. I see that I get back a
> StaxSource (CXF StaxSource, not javax StAXSource) in this case so I tried
> using that as the input next: Dispatch<Source> disp =
> service.createDispatch(new QName("urn:ihe:iti:xds-b:2007",
> "DocumentRegistry_Port_Soap12"), Source.class, Service.Mode.PAYLOAD, new
> AddressingFeature()); InputStream is =
> IBServer.class.getResourceAsStream("RegistryQuery.xml"); XMLInputFactory
> xmlInputFactory = XMLInputFactory.newFactory();
> XMLStreamReader xmlStreamReader =
xmlInputFactory.createXMLStreamReader(is,
> "UTF-8"); StaxSource staxSource = new StaxSource(xmlStreamReader);
> Source response = disp.invoke(staxSource);
>
> StaxSource also sent the same wrong action header. I also tried SAXSource:
> InputSource inputSource = new InputSource(is);
> SAXSource saxSource = new SAXSource(inputSource);
> Source response = disp.invoke(saxSource);
>
> And lastly I tried javax's StAXSource:
> //StaxSource staxSource = new StaxSource(xmlStreamReader);
> StAXSource staxSource = new StAXSource(xmlStreamReader);
> Source response = disp.invoke(staxSource);
>
> I thought maybe one of these was one of the cases you referred to, but
> assume I misunderstood or am doing something else wrong. Or maybe this
> only works in soap 1.1 wsdls or something?
>
> Thanks,
> Jesse
>
> -----Original Message-----
> From: Daniel Kulp [mailto:[email protected]]
> Sent: Wednesday, August 17, 2011 10:29 AM
> To: [email protected]
> Cc: Jesse Pangburn
> Subject: Re: dispatch api with ws-addressing
>
> On Wednesday, August 17, 2011 12:15:53 PM Jesse Pangburn wrote:
> > Hi,
> > Thanks for the suggestion, that will work. I was hoping there was some
> > way for CXF to do it automatically from the WSDL and the message body,
> > but this manual step is at least simple and makes sense.
>
> In SOME cases it can, but I'm not sure if StreamSource is one of them.
>
> Another option is:
>
> disp.getRequestContext().put(MessageContext.WSDL_OPERATION,
> new QName(ns, "myOperation")
>
> which will tell CXF what operation that dispatch is mapped to.
>
> One note: you may want to switch from StreamSource to just "Source" if
> possible. StreamSource is really the worse of the possible source types
> from a performance standpoint. On the incoming side, we pretty much suck
> the message into a byte[] or file and re-wrapper that with a new parser.
> Kind of crappy. If you do Provider<Source>, you would likely get a
> subclass of SAXSource which would allow us to maintain some level of
> streaming.
>
> Dan
>
> > Thank you,
> > Jesse
> >
> > -----Original Message-----
> > From: Aki Yoshida [mailto:[email protected]]
> > Sent: Wednesday, August 17, 2011 2:09 AM
> > To: [email protected]
> > Subject: Re: dispatch api with ws-addressing
> >
> > Hi,
> > you need to set the soap action in the dispatch client's request
> > context.
> > In your case, you need to add the following line:
> >
> > disp.getRequestContext().put(BindingProvider.SOAPACTION_URI_PROPERTY,
> > "urn:ihe:iti:2007:RegistryStoredQuery") ;
> >
> > Regards, aki
> >
> > 2011/8/17 Jesse Pangburn <[email protected]>:
> > > Hi,
> > > I'm trying to use the dispatch API and while I can make the service
> > > call ok, the ws-address "action" header is wrong. Here's my code:
> > > URL wsdlURL = new
> > > URL("file:/home/jpangburn/Desktop/IHE/XDSb.Support.Materials.v9/wsdl
> > > /XD
> > > S.b_DocumentRegistry.wsdl"); Service service =
> > > Service.create(wsdlURL,
> > > new QName("urn:ihe:iti:xds-b:2007", "DocumentRegistry_Service"));
> > > Dispatch<StreamSource> disp = service.createDispatch(new
> > > QName("urn:ihe:iti:xds-b:2007", "DocumentRegistry_Port_Soap12"),
> > > StreamSource.class, Service.Mode.PAYLOAD, new AddressingFeature());
> > > InputStream is =
> > > IBServer.class.getResourceAsStream("RegistryQuery.xml");
> > > StreamSource
> > > request = new StreamSource(is);
> > >
> > > StreamSource response = disp.invoke(request);
> > >
> > > Basically, I try to create a service from a WSDL with the service
> > > QName, then create a Dispatch from the port's QName while passing
> > > "new AddressingFeature()" to turn on WS-Addressing. The action
> > > header comes out like this: <Action
> > > xmlns="http://www.w3.org/2005/08/addressing">http://cxf.apache.org/j
> > > axw
> > > s/dispatch/DocumentRegistry_PortType/InvokeRequest</Action>
> > >
> > > This is wrong because the SOAP12 binding's operation has the
> > > following:
> > > <soap12:operation
> > > soapAction="urn:ihe:iti:2007:RegistryStoredQuery"/>
> > >
> > > So the header should be:
> > > <Action
> > > xmlns="http://www.w3.org/2005/08/addressing">urn:ihe:iti:2007:Regist
> > > ryS
> > > toredQuery</Action>
> > >
> > > All I can guess is that the Dispatch API doesn't know which
> > > operation
> > > I'm calling so it makes up this generic action header for the port
> > > instead of looking at the message I'm sending, determining the
> > > operation called, and grabbing the correct soap action to use in the
> > > action header. Am I doing something wrong or is this a limitation
> > > in
> > > the Dispatch API's support for WS-Addressing?
> > >
> > > Thanks,
> > > Jesse
--
Daniel Kulp
[email protected]
http://dankulp.com/blog
Talend - http://www.talend.com