[
http://jira.codehaus.org/browse/JIBX-228?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Dennis Sosnoski resolved JIBX-228.
----------------------------------
Resolution: Fixed
Fix Version/s: (was: JiBX 1.1.6)
JiBX 1.2.2
Added test cases for various combinations of namespace declarations and usages,
fixed code to correctly check for existing namespace declarations on
marshalling and add new ones where necessary.
> ArrayIndexOutOfBoundsException caused by org.jibx.extras.DomMapperBase
> ----------------------------------------------------------------------
>
> Key: JIBX-228
> URL: http://jira.codehaus.org/browse/JIBX-228
> Project: JiBX
> Issue Type: Bug
> Components: core
> Affects Versions: JiBX 1.1.6
> Environment: JiBX v1.1.6a
> JDK v1.5.0_06
> Eclipse IDE "Ganymede" v3.4 + JiBX eclipse plugin activated
> Reporter: Alexandre Delarge
> Assignee: Dennis Sosnoski
> Fix For: JiBX 1.2.2
>
> Attachments: jibx-jira.zip, jira-jibx-228.txt
>
>
> Hello,
> I refactored a web service application that made heavy usage of DOM
> generation/parsing to use JiBX instead.
> While working on this, I wrote a couple JiBX bindings that rely on the
> "org.jibx.extras.DomElementMapper" class that comes as a part of JiBX extras.
> Using this mapper to marshall arbitrary portions of DOM trees raised a number
> of ArrayIndexOutOfBoundsException that prevented my application to success in
> generating response messages.
> I drilled down these error causes into JiBX source code, and here is what I
> found (note: all references to source code below are taken from v1.1.6a).
> 1) Lookup of known namespaces & prefixes
> ==================================
> In class "org.jibx.extras.DomMapperBase", in many places inside the method
> "findNamespaceIndex" you return -1 if you don't find a namespace prefix among
> the list owned by the m_xmlWriter object.
> Here is an example on line 123:
> ---
> [...]
> int index = m_xmlWriter.getPrefixIndex(prefix);
> if (index >= 0) {
> return getNamespaceUri(index).equals(uri) ?
> index : -1;
> } else { // line 122
> return -1; // line 123
> }
> [...]
> ---
> This -1 value greatly increases the chances of getting an
> ArrayIndexOutOfBoundsException from method "getNamespacePrefix(int index)" in
> class "org.jibx.runtime.impl.XMLWriterNamespaceBase".
> The -1 value results from a failure in finding the exact given prefix in the
> list of prefixes the m_xmlWriter object owns.
> I think that looking for the namespace itself inside the list of namespace
> URIs owned by the m_xmlWriter object will do the right job, while suppressing
> many of the exceptions.
> To me it sounds valid, because it happens that the namespace URI is known but
> just associated to a different prefix.
> During the marshalling of various DOM elements, I got bothered by this
> missing lookup in several places, so I implemented it into a new private
> method:
> ---
> /**
> * Get index number for declared namespace.
> *
> * @param uri namespace URI (empty string if none)
> * @return namespace index number, or <code>-1</code> if not declared or
> * masked
> */
> private int findNamespaceURIIndex(String uri) {
> String[] uris = m_xmlWriter.getNamespaces();
> for (int i = 0; i < uris.length; i++) {
> if(uris[i].equals(uri)) {
> return i;
> }
> }
> return -1;
> }
> ---
> Then I updated the "findNamespaceIndex" method accordingly, in the 3
> following locations (lines 108, 115, and 123):
> ---
> [...]
> } else {
> return findNamespaceURIIndex(uri); // line 108
> }
> } else {
> return -1;
> }
> } else {
> return m_defaultNamespaceURI.equals(uri) ?
> m_defaultNamespaceIndex : findNamespaceURIIndex(uri); // line 115
> }
> } else {
> int index = m_xmlWriter.getPrefixIndex(prefix);
> if (index >= 0) {
> return getNamespaceUri(index).equals(uri) ?
> index : -1;
> } else {
> return findNamespaceURIIndex(uri); // line 123
> }
> [...]
> ---
> 2) Discovery of namespaces & prefixes
> ==============================
> I also had troubles with the strategy for handling some namespaces
> declarations coming from a DOM tree, with the same kind of symptoms showing
> up: ArrayIndexOutOfBoundsException rising from class
> "org.jibx.runtime.impl.StreamWriterBase", more exactly from method
> "writePrefix".
> For that one I had to look closely at method "marshalElement" in class
> "org.jibx.extras.DomElementMapper", stepping into the algorithm for getting
> the right namespace index for the current element.
> Actually, I think the following assignment at line 227 (by the way is the
> "==" operator wanted here, or is it "equals()" ?):
> ---
> [...]
> if (uri == decluri) {
> nsi = defind; // line 227
> }
> [...]
> ---
> Will occasionally de-activates the lookup for the right index among newly
> discovered namespaces, which is made at line 251:
> ---
> [...]
> for (int i = 0; i < length; i++) {
> prefs[i] = (String)nss.get(i*2);
> uris[i] = (String)nss.get(i*2+1);
> nums[i] = base + i;
> if (nsi < 0 && uri.equals(uris[i])) { // line 251
> if ((prefix == null && prefs[i] == "") ||
> (prefix != null && prefix.equals(prefs[i]))) {
> nsi = base + i;
> }
> }
> }
> [...]
> ---
> This may result in an incorrect index being used, because the lookup made at
> line 251 takes into account the index shift introduced by the addition of new
> namespaces, while this assignment does not.
> I therefore remove it.
> However the main issue with that method in my humble opinion is the fact we
> don't check that we have found the element's namespace index just after we
> checked all the attributes for namespaces declarations.
> I therefore added the following statements just before line 233:
> ---
> [...]
> /*
> * if we get there without having found an index for the current
> * element's namespace, we add it to the list.
> */
> if(nsi == -1 && (nss == null || !nss.contains(uri))) {
> if(nss == null) nss = new ArrayList();
> nss.add(prefix == null ? "" : prefix);
> nss.add(uri == null ? "" : uri);
> }
> [...]
> ---
> I don't alter the value of "nsi", so the aforementioned lookup located at
> line 251 will assign it with the right value.
> I attach a sample Eclipse project to this report, it contains a sample set of
> Java classes, XML file, and binding that exhibits the 2nd issue (I cannot
> easily cause the 1st one to happen).
> The code I bundle features a JUnit test case in class
> "test.jibx.junit.TestDomMapper".
> I include my version of the "DomMapperBase" class, which enables the code I
> wrote to work fine.
> I also include a visual summary of the differences between the original
> version, of the class and mine, hoping this will help.
> Regards,
> Alex.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
------------------------------------------------------------------------------
SOLARIS 10 is the OS for Data Centers - provides features such as DTrace,
Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW
http://p.sf.net/sfu/solaris-dev2dev
_______________________________________________
jibx-devs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jibx-devs