[
http://issues.apache.org/jira/browse/AXIS2-608?page=comments#action_12376722 ]
Chuck Williams commented on AXIS2-608:
--------------------------------------
Hi Ajith,
Unfortunately the issue will need to remain open. I just tried my application
and it failed with the latest axis2 from svn. This failure is for minOccurs=0,
and I'm pretty sure other cases will fail too, including more complex cases of
recursive data types that I didn't reach. I continue to hold by my position
that the parsing can never be right if a loop invariant is not established for
the reader position. Otherwise, you are forced to guess and cannot guess
correctly in all cases. Here is the failing code from my applicaiton and the
diagnosis as to why it is failing:
Here is the relevant wsdl:
<xsd:element name="stringListResponseElement"
type="asxsd:StringListResponseType"/>
<xsd:complexType name="StringListResponseType">
<xsd:choice>
<xsd:element name="stringList" type="asxsd:StringList"/>
<xsd:element name="exception" type="asxsd:ExceptionType"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="StringList">
<xsd:sequence>
<xsd:element name="s" type="xsd:string" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
And here is the problematic parse() method generated by the lastest axis2:
public static StringList parse(javax.xml.stream.XMLStreamReader
reader) throws java.lang.Exception{
StringList object = new StringList();
try {
int event = reader.getEventType();
//event better be a START_ELEMENT. if not we should go up to the
start element here
while (event!= javax.xml.stream.XMLStreamReader.START_ELEMENT) {
event = reader.next();
}
org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine stateMachine1
= new
org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine();
stateMachine1.setElementNameToTest(new
javax.xml.namespace.QName(
"",
"s"));
stateMachine1.setCanbeAbsent(true);
stateMachine1.read(reader);
java.lang.String[] textArray1 =
stateMachine1.getTextArray();
object.setS(
(java.lang.String[])
org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
java.lang.String.class,textArray1));
} catch (javax.xml.stream.XMLStreamException e) {
throw new java.lang.Exception(e);
}
return object;
}
When passed a valid <stringListResponseElement> with inner <stringList> that
contains <s> elements as produced by the pull parser on the server side, here
is the exception that is generated parsing this response on the client side:
java.lang.RuntimeException: java.lang.RuntimeException: Unexpected subelement s
at
org.apache.axis2.AnalysisServiceStub.fromOM(AnalysisServiceStub.java:13495)
at
org.apache.axis2.AnalysisServiceStub.listInvestigations(AnalysisServiceStub.java:1752)
at
com.metalincs.analysiswebclient.actions.ListInvestigationsAction.execute(ListInvestigationsAction.java:55)
at
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:419)
at
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:224)
at
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:362)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856)
at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:744)
at
org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at
org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at
org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
Caused by: java.lang.RuntimeException: Unexpected subelement s
at
org.apache.axis2.AnalysisServiceStub$StringListResponseType$Factory.parse(AnalysisServiceStub.java:4738)
at
org.apache.axis2.AnalysisServiceStub$StringListResponseElement$Factory.parse(AnalysisServiceStub.java:4511)
at
org.apache.axis2.AnalysisServiceStub.fromOM(AnalysisServiceStub.java:13459)
... 25 more
And here is the diagnosis:
I traced through the code. The problem is that the parse() method for
StringList above has not advanced the reader when it starts parsing the
properties. The reader is still pointed at the outer <stringList> when the
state machine is called to parse the <s> elements. The <s> elements have
minOccurs=0 and so can be omitted. The state machine sees the <stringList>
element, which is not <s> and so it concludes there were no <s> elements. It
returns and empty array rather than the correct array of the <s> element
values. Then in the parse method for StringListResponseType it sees an <S>
element which is not legal there and so it generates the exception. The
failure is in not parsing the <stringList> properly.
The problem would be resolved by adding one line of code to position the reader
for parsing the properties:
public static StringList parse(javax.xml.stream.XMLStreamReader
reader) throws java.lang.Exception{
StringList object = new StringList();
try {
int event = reader.getEventType();
//event better be a START_ELEMENT. if not we should go up to the
start element here
while (event!= javax.xml.stream.XMLStreamReader.START_ELEMENT) {
event = reader.next();
}
// ********* Advance reader to properties *********************
reader.next();
org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine stateMachine1
= new
org.apache.axis2.databinding.utils.SimpleArrayReaderStateMachine();
stateMachine1.setElementNameToTest(new
javax.xml.namespace.QName(
"",
"s"));
stateMachine1.setCanbeAbsent(true);
stateMachine1.read(reader);
java.lang.String[] textArray1 =
stateMachine1.getTextArray();
object.setS(
(java.lang.String[])
org.apache.axis2.databinding.utils.ConverterUtil.convertToArray(
java.lang.String.class,textArray1));
} catch (javax.xml.stream.XMLStreamException e) {
throw new java.lang.Exception(e);
}
return object;
}
The <choice> template is careful about always positioning the reader correctly
per my earlier description in this bug. Doing this makes everything much
simpler. I continue to not see any way to parse without correct reader
positioning.
It's 2:00 AM here and so I'm done for the day, but if this is still open
tomorrow morning I will try to patch the template (and verify the state
machines always position the reader consistently when they finish).
Chuck
> Generated ADB code fails on omitted scalar minOccurs=0 elements and recursive
> data types
> ----------------------------------------------------------------------------------------
>
> Key: AXIS2-608
> URL: http://issues.apache.org/jira/browse/AXIS2-608
> Project: Apache Axis 2.0 (Axis2)
> Type: Bug
> Components: databinding
> Versions: 1.0
> Environment: All
> Reporter: Chuck Williams
> Assignee: Ajith Harshana Ranabahu
> Attachments: codegen.patch
>
> The patches I submitted previously (AXIS2-523) to fix various cases of
> minOccurs=0 and recusive data types have been applied in 1.0 RC2 only for
> elements whose types are choice particles. The underlying problems remain in
> all other cases.
> One case of minOccurs=0 that fails is for an omitted scalar element
> (maxOccurs=1). Consider a simple string-valued element S, and a element C
> that contains S with minOccurs=0. The Factory.parse() method for C generates
> code to parse S that creates a SimpleElementReaderStateMachine with
> setElementNameToTest() S and then calls it. But there is no S, so the state
> machine fails.
> An example of a recusive data type problem occurs when an element E contains
> an array-valued sub-element also named E. The parser for the outer E leaves
> the reader positioned at its own start element and then proceeds to search
> for the array by scanning forward looking for the first <E>. It find itself
> and not the inner E!
> The patch resolves this issue and a set of related issues by creating a loop
> invariant for the reader position. Specifically, the reader is always after
> the end element of the prior element (or initially after the outer start
> element) when it seeks to parse an inner element. I don't believe the code
> generator can ever parse correctly without having the reader position be a
> loop invariant. This is why getElementTextProperly() is essential -- because
> getElementText() itself fails to position the reader properly in some cases
> and it is unfortunately now in commons, as documented in the comment in
> ADBBeanTemplate.xsl.
> I was able to resolve these issues by using in all cases the template that
> RC2 calls out as a special case for choice particles, i.e., by simply
> deleting the altnerative template. Perhaps there are issues with this
> template that caused it to be called out specially and used only for <choice>
> particles, but I do not know what they are. I have a complex application
> that uses all of these wsdl features and more that is working perfectly with
> this template.
> All axis2 tests pass with this template, but only after fixing a bug in one
> test that is related to the issues here (PopulateMinOccurs0Test failed when
> an omitted MinOccurs=0 parameter was actually missing).
> The attached patch against modules/codegen fixes the issues in both
> ADBBeanTemplate.xsl and PopulateMinOccurs0Test.java. This patch also
> contains the patch at AXIS-607.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira