[jdom-interest] JDOM 2 list of elements, remove nulls out entries and fails to remove?

Rolf Lear jdom at tuis.net
Fri May 11 19:47:34 PDT 2012


Right, I believe I have reproduced it....

Hmmm... still working it.


package org.jdom2.test.cases;

import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import org.jdom2.Element;

@SuppressWarnings("javadoc")
public class TestMultipleFilterLists {

	private static final Element getRoot() {
		Element root = new Element("root");
		root.addContent(new Element("A"));
		root.addContent(new Element("B"));
		root.addContent(new Element("C"));
		root.addContent(new Element("A"));
		root.addContent(new Element("B"));
		root.addContent(new Element("C"));
		root.addContent(new Element("A"));
		root.addContent(new Element("B"));
		root.addContent(new Element("C"));
		root.addContent(new Element("A"));
		root.addContent(new Element("B"));
		root.addContent(new Element("C"));
		return root;
	}
	
	@Test
	public void testMultiLists() {
		Element root = getRoot();
		List<Element> as = root.getChildren("A");
		List<Element> bs = root.getChildren("B");
		List<Element> cs = root.getChildren("C");
		
		for (Element f : as) {
			assertTrue("A".equals(f.getName()));
		}
		for (Element f : bs) {
			assertTrue("B".equals(f.getName()));
		}
		for (Element f : cs) {
			assertTrue("C".equals(f.getName()));
		}
		
		final int bsz = bs.size();
		final int csz = cs.size();
		
		while (!as.isEmpty()) {
			final int sz = as.size() - 1;
			Element e = as.get(0);
			as.remove(e);
			
			assertTrue(sz == as.size());
			assertTrue(bsz == bs.size());
			assertTrue(csz == cs.size());
			
			for (Element f : as) {
				assertTrue("A".equals(f.getName()));
			}
			for (Element f : bs) {
				/******  THROWS NULL POINTER ******/
				assertTrue("B".equals(f.getName()));
			}
			for (Element f : cs) {
				assertTrue("C".equals(f.getName()));
			}
		}
		
		
	}

}



Rolf



On 11/05/2012 10:17 PM, David Wall wrote:
> Okay,
>
> Attached is the XML I was parsing. In particular, I noted the null
> pointer on the elements DropDown and DropDownVersion. There should be a
> one-to-one correspondence between these two elements, with the
> DropDownVersion containing a dropDownId that links it to the DropDown
> element.
>
> I have also attached the source code file, but it's not a nice test
> case. I have a few areas with "JDOM:" comments that are geared for you.
>
> Thanks,
> David
>
> On 5/11/2012 7:02 PM, Rolf Lear wrote:
>> Please send the code.... put a comment in it where you think the
>> failure is..... Under no condition should JDOM return a null value...
>>
>> Rolf
>>
>> On 11/05/2012 9:45 PM, David Wall wrote:
>>> Thanks, Rolf. No, it's definitely not a threading issue. If you saw my
>>> second posting, it all works as expected if I create my own
>>> LinkedList<Element> from the list returned by getChildren().
>>>
>>> If you think it's still a possible issue, I can attached the actual
>>> source code and the sample XML data I was parsing. I'm not familiar with
>>> JDOM's internals, but if I remove one Element, does that cause a shift
>>> for all subsequent elements? I ask this because I am actually creating
>>> two lists, one is the main object, and the second is an associated
>>> "version" object (the main object can have multiple versions associated
>>> with it). In the XML, they are ordered like OBJ, OBJVERSION, OBJ,
>>> OBJVERSION, OBJ, OBJVERSION.
>>>
>>> When I created to the two lists (one of OBJ and the other of
>>> OBJVERSION), I noted that as soon as I deleted the OBJ from the first
>>> list, the second list already showed a 'null' element at the end of its
>>> list. It made me think that the elements are shifting in the live lists
>>> from JDOM and thus I'm no longer working on the originally retrieved
>>> lists.
>>>
>>> So, if that's all it is and my usage scenario was bogus before, I'm good
>>> since I've changed to create my own lists now. But if you think it could
>>> still be an issue, I'm happy to send the code and XML to you (it's open
>>> source code anyway).
>>>
>>> Thanks,
>>> David
>>>
>>>
>>> On 5/11/2012 6:14 PM, Rolf Lear wrote:
>>>> Hi David.
>>>>
>>>> This problem you describe is very concerning, and should not, in
>>>> 'supported' usage ever happen....
>>>>
>>>> I am wracking my brains to figure out what it could be, but, the only
>>>> think I can think is that you are accessing the JDOM objects from
>>>> different threads.... JDOM is *not* thread safe.
>>>>
>>>> If this is happening in a single-threaded mechanism, would it be
>>>> possible to put together a failing 'test case', any code that shows
>>>> the problem?
>>>>
>>>> I have to admit that I thought he iteration/remove/add/etc. type code
>>>> is very well tested, and I would be *very* suprised if there is a
>>>> problem like this.... in fact, I know that there are test cases that
>>>> cover this basic condition that you describe... and they never fail....
>>>>
>>>> so, if you can confirm this is all happening in one thread.... and
>>>> preferably if you can put together an example of the problem, I would
>>>> look in to it immediately....
>>>>
>>>> Rolf
>>>>
>>>> On 11/05/2012 8:42 PM, David Wall wrote:
>>>>> I believe I've run into a problem that I don't think I had with JDOM
>>>>> 1.1.3 before I upgraded to 2.0.1.
>>>>>
>>>>> I create a list of elements of a selected element using:
>>>>>
>>>>> List<?> documentVersionElements =
>>>>> rootElement.getChildren("DocumentVersion", ns);
>>>>>
>>>>> I see that I have 6 elements as expected in my list. None are null.
>>>>>
>>>>> I am basically then trying to find a matching related element id in
>>>>> that list using something like:
>>>>>
>>>>> Element found = null;
>>>>> ListIterator<?> iter = documentVersionElements .listIterator();
>>>>> while( iter.hasNext() ) {
>>>>> Element checkElement = (Element)iter.next();
>>>>> EsfUUID evParentId = new
>>>>> EsfUUID(checkElement.getChildText("documentId", ns));
>>>>> if ( evParentId.equals(id) ) {
>>>>> found = checkElement;
>>>>> break;
>>>>> }
>>>>> }
>>>>>
>>>>> Then, assuming I find it (found != null), I process it as expected.
>>>>> But I then want to remove the found element from the element list so
>>>>> it cannot be found again, so I use this:
>>>>>
>>>>> documentVersionElements.remove(found);
>>>>>
>>>>> Most of the time, this seems to work as expected, and the
>>>>> documentVersionElements list is then shorter by 1. But there are
>>>>> times when a list of 6 elements remains 6 elements after the remove
>>>>> (and remove() returns false), with 4 of them now null (not removed,
>>>>> but actually a null element), so in when I return to the
>>>>> listIterator() above and get my next() element, the element is null.
>>>>>
>>>>> It's as if my Element objects are not unique in the list in terms of
>>>>> equals/hashCode as my elements should never be nulled out.
>>>>>
>>>>> I am not sure why an element I find by iterating cannot then be
>>>>> removed. How could it fail to remove? Why would it change other list
>>>>> elements to NULL instead? Is this not a valid usage pattern?
>>>>>
>>>>> Thanks,
>>>>> David
>>>>> _______________________________________________
>>>>> To control your jdom-interest membership:
>>>>> http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com
>>>>>
>>>>>
>>>>
>>>
>>



More information about the jdom-interest mailing list