You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Matt Benson (JIRA)" <ji...@apache.org> on 2007/01/11 00:01:27 UTC

[jira] Resolved: (JXPATH-68) StackOverflow error on a call to 'JXPathContext.createPath()'

     [ https://issues.apache.org/jira/browse/JXPATH-68?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Matt Benson resolved JXPATH-68.
-------------------------------

    Resolution: Fixed

The bottom line here is that your AbstractFactory implementation is faulty.  Per the contract of AbstractFactory.createObject(), when you return true from this method you are signifying that you have created a (non-null) value at the specified place in the object hierarchy.  The only thing that can be done is to install a check to detect the situation and throw a meaningful exception informing you of your error.  This change has been made in SVN HEAD for commons-jxpath 1.3 .

Regards,
Matt

> StackOverflow error on a call to 'JXPathContext.createPath()'
> -------------------------------------------------------------
>
>                 Key: JXPATH-68
>                 URL: https://issues.apache.org/jira/browse/JXPATH-68
>             Project: Commons JXPath
>          Issue Type: Bug
>    Affects Versions: Nightly Builds, 1.2 Final
>         Environment: Windows XP Professional, Sun JDK 1.4.2
> Run with JXPath v1.2 and v20060530
>            Reporter: Joseph Campolongo
>             Fix For: 1.3
>
>
> I'm running into a StackOverflow error on a call to
> 'JXPathContext.createPath()' whenever I have a path that looks like
> 'a/b[1]/c'.  I took a quick look at the code and it appears JXPath, when
> trying to create its parent pointer, simply recreates an equivalent
> pointer(???).
> Here is code to reproduce the problem.
>     Map map = new HashMap();
>     map.put("a", null);
>     
>     JXPathContext pathContext = JXPathContext.newContext(map);
>     pathContext.setFactory(new AbstractFactory() {
>       public boolean createObject(
>           JXPathContext context, Pointer pointer, Object parent, String
> name, int index) {
>         Map parentMap = (Map)parent;
>         System.out.println(parent + ":" + name + ":" + index);
>         if (index > -1) {
>           List list = (List)parentMap.get(name);
>           if (list == null) {
>             list = new ArrayList();
>           }
>           int size = list.size();
>           for (int i = size; i <= index; i++) {
>             list.add(i, null);
>           }
>           parentMap.put(name, list);
>         } else {
>           parentMap.put(name, new HashMap());
>         }
>         return true;
>       }
>       
>     });
>     pathContext.createPath("a/b[1]/c");
> ***************
> I have continued looking into this, and found that the problem is that, if
> the List is created with a 'null' element, JXPath gets stuck in infinite
> recursion.
> To discover this, I changed my Factory to implement the following method:
>       public boolean createObject(
>           JXPathContext context, Pointer pointer, Object parent, 
>           String name, int index) {
>         if (pointer instanceof NodePointer) {
>           index = ((NodePointer)pointer).getIndex();
>         }
>         System.out.println(parent + ":" + name + ":" + index);
>         Map parentMap = (Map)parent;
>         if (index > -1) {
>           List list = (List)parentMap.get(name);
>           if (list == null) {
>             list = new ArrayList();
>           }
>           int size = list.size();
>           for (int i = size; i <= index; i++) {
>             list.add(i, new HashMap());  // !!!!!!  Don't set to 'null'
>           }
>           parentMap.put(name, list);
>         } else {
>           parentMap.put(name, new HashMap());
>         }
>         return true;
>       }
> Then I ran the following code:
>     pathContext.createPath("a/b[1]/c");
>     pathContext.createPath("a/b[2]/c");  // STACK OVERFLOW HERE
> Here is the stack trace at the beginning, where
> 'ValueUtils.expandCollection()' is called.  It puts 'null' into the list,
> thus causing the stack overflow as we cycle between createPath() &
> createChild().
> Thread [main] (Suspended (breakpoint at line 227 in DynamicPropertyPointer))
> 	DynamicPropertyPointer.createPath(JXPathContext) line: 227
> 	DynamicPropertyPointer(PropertyPointer).createChild(JXPathContext,
> QName, int) line: 188
> 	NullElementPointer.createPath(JXPathContext) line: 82
> 	NullPointer.createPath(JXPathContext) line: 86
> 	NullPropertyPointer.createPath(JXPathContext) line: 103
> 	NullPointer.createPath(JXPathContext) line: 86
> 	NullPropertyPointer.createPath(JXPathContext) line: 103
> 	JXPathContextReferenceImpl.createPath(String, Expression) line: 447
> 	JXPathContextReferenceImpl.createPath(String) line: 427
> 	Test.test4() line: 75
> 	Test.main(String[]) line: 38

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: https://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org