You are viewing a plain text version of this content. The canonical link for it is here.
Posted to j-users@xerces.apache.org by "Newman, John W" <ne...@d3onc.com> on 2011/07/19 18:01:02 UTC

RE: DOM thread safety issues & disapearring children

I just wanted to follow up and say that switching off deferred parsing did not add any stability.  Still the same issues, same steps to reproduce everytime.  And yes it is actually on, my elements did change from DeferredElementImpl to ElementImpl.  So no dice there.

Also setting the node to readonly didn't work either, but I didn't really expect it to since that's for modifying the DOM and not clobbering the underlying unsafe state.

Let me ask you this then .. since clearly there is an industry need for a thread safe document (like the one person said this comes up ALL the time), and you are pretty clear that the default implementation will always remain unsafe - "it's up to the caller to add the locks",  why can't you provide a simple extension of the current implementation that properly takes care of the syncing at a higher level but in-between the caller and the unsafe impl?  Effectively do what I'm scrambling to do correctly and offload this burden...

class  ThreadSafeDeferredElementImpl extends DeferredElementImpl  {
   @Override
   public void iAmNotTotallySureWhatMethodsNeedSycned()  {
      synchronzized (this.something)  {
         return this.something.whatever();
      }
  }
}

Isn't that easy to do and win win?  You can maintain your "it's not thread safe stance", and users that don't require thread safety will still have the good performance, but users like us that essentially need to ditch your library can have the syncing properly taken care of and out of our code.  Why not just do that?

Thanks,
John



From: Michael Glavassevich [mailto:mrglavas@ca.ibm.com]
Sent: Wednesday, June 08, 2011 12:06 AM
To: j-users@xerces.apache.org
Subject: Re: DOM thread safety issues & disapearring children


Hi John,

None of Xerces' DOM implementations are thread-safe, even the non-deferred ones. This is true even for read operations. In particular, the implementation of the NodeList methods (i.e. item() and getLength()) are not thread-safe. These methods do some internal writes to a cache which are necessary for good performance. There's a longer explanation in the JIRA issue you found.

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com<ma...@ca.ibm.com>
E-mail: mrglavas@apache.org<ma...@apache.org>

"Newman, John W" <ne...@d3onc.com>> wrote on 06/07/2011 04:17:22 PM:

> All,
>
> My team has built a web application that has a few components that
> rely heavily on the xerces DOM implementation.  Unfortunately a lot
> of this was developed before we even learned that the node
> implementations are deliberately not thread safe. =)  I've added a
> few sync blocks where appropriate (I think), and everything is
> functioning ok except for two remaining issues.
>
> 1)      Under very high load, an element will somehow lose nearly
> all of its children.
> <root>
>   <ch0 />
>   <ch0 />
>   <ch0 />
>   <ch1 />
>   <ch1 />
>   <ch2><ch2.1 /></ch2>
>   <ch3><ch3.1><ch3.2 /></ch3.1></ch3>
>   .... Rather large document, many levels of nesting
> </root>
>
> That will sit there and work fine for a few days, until something
> (?) happens and most of the children will disappear .  I cannot
> isolate this problem at all, it has been very difficult to track
> anything down so I'm asking for help.  There are no exceptions in
> the log or anything otherwise to indicate that something bad is
> happening.  One day I saw
>
> <root>
>   <ch0 />
>   <ch0 />
> </root>
>
> And then a few days later
>
> <root>
>   <ch0 />
>   <ch0 />
>   <ch0 />
>   <ch1 />
> </root>
>
> The fact that there doesn't seem to be any pattern to which children
> stay vs. which disappear, and only under higher load has me
> suspecting thread safety.  In general it seems like the smaller
> elements at the top are more likely to hang around, but again
> there's no real pattern.  We are not doing any modification on these
> nodes, in fact I want to make them read only.  I'm debating on
> casting the org.w3c.Node to org.apache.xerces.dom.NodeImpl and
> calling setReadOnly(true, true)  on it to freeze it - but the
> javadoc says I probably shouldn't need that method?  If I did that,
> I'd at least get a stack trace when whatever it is decides to modify
> it.  Does that sound like a good approach?  Is there anything
> obvious that would cause this problem, e.g. has anyone ran into this
> before?  Am I missing a sync?  I'm about stumped.
>
> 2)       Also under high load, I occasionally get this stack trace
> (this is not the cause of or symptom of item 1, it is a separate
> issue occurring at separate times)
>
> java.lang.NullPointerException:
> (no message)
> at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
> at org.apache.xerces.dom.ParentNode.item(Unknown Source)
> at freemarker.ext.dom.NodeListModel.<init>(NodeListModel.java:89)
> at freemarker.ext.dom.NodeModel.getChildNodes(NodeModel.java:302)
> at freemarker.ext.dom.ElementModel.get(ElementModel.java:124)
> at freemarker.core.Dot._getAsTemplateModel(Dot.java:76)
>
> Again I'm suspecting thread safety and a missing sync.    Just
> refreshing the page works ok.  I raised the issue with freemarker
> since it's only their stack frames calling the DOM, so I figured the
> burden falls on them to sync.  But they passed the puck back to me
> and said 'we do not guarantee thread safety if your data model is
> not thread safe to begin with.'  They're not going to go and add
> sync blocks all over their code due to an implementation artifact of
> your library, and I would agree with that.  Really the lack of
> thread safety even for reads is a pretty poor fit for a web
> application...  How do I fix this problem, in general is there a way
> to make this library more thread safe?  The best suggestion I have
> for that stack trace so far is to use CGLib to proxy the element and
> inject sync blocks where they should be.  Ugh...  https://
> issues.apache.org/jira/browse/XERCESJ-727 is relevant here
>
> What about calling documentBuilderFactory.setFeature("http://
> apache.org/xml/features/dom/defer-node-expansion<http://%0b%3e%20apache.org/xml/features/dom/defer-node-expansion>", false);   to turn
> off lazy parsing?  Does that guarantee thread safety since
> everything is already parsed into ram and it's just read only?
>
>
> Any input is very much appreciated, these issues are affecting production.  K
>
> Thanks,
> John

RE: DOM thread safety issues & disapearring children

Posted by "Newman, John W" <ne...@d3onc.com>.
Yes just a thread safe API for read is all one would reasonably expect.  Writes to the DOM, sure I would provide thread locking around where I am doing the writes - I wouldn't expect the library to want to handle that.  But reads...

"transaction locking for a group of related changes."

I'm not making any changes, just presenting a view over xml.  Can't you provide an extension that would lock the few methods are read only to the DOM but yet doing writes to the internal state?  Yes?


From: gzunkal@googlemail.com [mailto:gzunkal@googlemail.com] On Behalf Of Alasdair Thomson
Sent: Tuesday, July 19, 2011 12:46 PM
To: j-users@xerces.apache.org
Subject: RE: DOM thread safety issues & disapearring children


I think the relevant complaint is that the DOM isn't thread safe for read-only operations, which is counter-intuitive unless you have knowledge of the underlying implementation. I don't think anyone expects it to be thread safe for updating.

I've tended to use JAXB to transform the XML to java objects, which I can then make sure are thread safe for read only operations.
On Jul 19, 2011 5:26 PM, <ke...@us.ibm.com>> wrote:
> In 99% of the use cases, locking the individual DOM objects/operations
> would be the wrong level of granularity -- what you really need to prevent
> unexpected results is transaction locking for a group of related changes.
> That really does have to be done at the application level.
>
> Locking every individual operation also can have significant performance
> impact, in these days of multikernel/multiprocessor machines, due to the
> need to flush cache in order to make sure all the processors know the
> lock's state has changed. The days of "synchronize is free" really are
> over.
>
> Also, frankly, I would be reluctant to encourage people to rely on a
> protected DOM since if/when they change platforms their code will break
> unexpectedly.
>
> If you really want locks on every operation, you're free to build a
> "threadsafe DOM manipulation" library which provides threadsafety -- eg
> static Threadsafe.appendChild(Node parent, Node newChild). The code won't
> look exactly like a simple DOM call, but in most JVMs this kind of simple
> "tail call" is pretty efficient, it makes what you're doing explicit, and
> it's portable to any DOM you care to throw at it.
>
>
> ______________________________________
> "You build world of steel and stone
> I build worlds of words alone
> Skilled tradespeople, long years taught:
> You shape matter; I shape thought."
> (http://www.songworm.com/lyrics/songworm-parody/ShapesofShadow.html)
>
>
>
> From:
> "Newman, John W" <ne...@d3onc.com>>
> To:
> "j-users@xerces.apache.org<ma...@xerces.apache.org>" <j-...@xerces.apache.org>>
> Date:
> 07/19/2011 11:49 AM
> Subject:
> RE: DOM thread safety issues & disapearring children
>
>
>
> I just wanted to follow up and say that switching off deferred parsing did
> not add any stability. Still the same issues, same steps to reproduce
> everytime. And yes it is actually on, my elements did change from
> DeferredElementImpl to ElementImpl. So no dice there.
>
> Also setting the node to readonly didn't work either, but I didn't really
> expect it to since that's for modifying the DOM and not clobbering the
> underlying unsafe state.
>
> Let me ask you this then .. since clearly there is an industry need for a
> thread safe document (like the one person said this comes up ALL the
> time), and you are pretty clear that the default implementation will
> always remain unsafe - "it's up to the caller to add the locks", why
> can't you provide a simple extension of the current implementation that
> properly takes care of the syncing at a higher level but in-between the
> caller and the unsafe impl? Effectively do what I'm scrambling to do
> correctly and offload this burden...
>
> class ThreadSafeDeferredElementImpl extends DeferredElementImpl {
> @Override
> public void iAmNotTotallySureWhatMethodsNeedSycned() {
> synchronzized (this.something) {
> return this.something.whatever();
> }
> }
> }
>
> Isn't that easy to do and win win? You can maintain your "it's not thread
> safe stance", and users that don't require thread safety will still have
> the good performance, but users like us that essentially need to ditch
> your library can have the syncing properly taken care of and out of our
> code. Why not just do that?
>
> Thanks,
> John
>
>
>
> From: Michael Glavassevich [mailto:mrglavas@ca.ibm.com<ma...@ca.ibm.com>]
> Sent: Wednesday, June 08, 2011 12:06 AM
> To: j-users@xerces.apache.org<ma...@xerces.apache.org>
> Subject: Re: DOM thread safety issues & disapearring children
>
> Hi John,
>
> None of Xerces' DOM implementations are thread-safe, even the non-deferred
> ones. This is true even for read operations. In particular, the
> implementation of the NodeList methods (i.e. item() and getLength()) are
> not thread-safe. These methods do some internal writes to a cache which
> are necessary for good performance. There's a longer explanation in the
> JIRA issue you found.
>
> Thanks.
>
> Michael Glavassevich
> XML Parser Development
> IBM Toronto Lab
> E-mail: mrglavas@ca.ibm.com<ma...@ca.ibm.com>
> E-mail: mrglavas@apache.org<ma...@apache.org>
>
> "Newman, John W" <ne...@d3onc.com>> wrote on 06/07/2011 04:17:22 PM:
>
>> All,
>>
>> My team has built a web application that has a few components that
>> rely heavily on the xerces DOM implementation. Unfortunately a lot
>> of this was developed before we even learned that the node
>> implementations are deliberately not thread safe. =) I've added a
>> few sync blocks where appropriate (I think), and everything is
>> functioning ok except for two remaining issues.
>>
>> 1) Under very high load, an element will somehow lose nearly
>> all of its children.
>> <root>
>> <ch0 />
>> <ch0 />
>> <ch0 />
>> <ch1 />
>> <ch1 />
>> <ch2><ch2.1 /></ch2>
>> <ch3><ch3.1><ch3.2 /></ch3.1></ch3>
>> .... Rather large document, many levels of nesting
>> </root>
>>
>> That will sit there and work fine for a few days, until something
>> (?) happens and most of the children will disappear . I cannot
>> isolate this problem at all, it has been very difficult to track
>> anything down so I'm asking for help. There are no exceptions in
>> the log or anything otherwise to indicate that something bad is
>> happening. One day I saw
>>
>> <root>
>> <ch0 />
>> <ch0 />
>> </root>
>>
>> And then a few days later
>>
>> <root>
>> <ch0 />
>> <ch0 />
>> <ch0 />
>> <ch1 />
>> </root>
>>
>> The fact that there doesn't seem to be any pattern to which children
>> stay vs. which disappear, and only under higher load has me
>> suspecting thread safety. In general it seems like the smaller
>> elements at the top are more likely to hang around, but again
>> there's no real pattern. We are not doing any modification on these
>> nodes, in fact I want to make them read only. I'm debating on
>> casting the org.w3c.Node to org.apache.xerces.dom.NodeImpl and
>> calling setReadOnly(true, true) on it to freeze it - but the
>> javadoc says I probably shouldn't need that method? If I did that,
>> I'd at least get a stack trace when whatever it is decides to modify
>> it. Does that sound like a good approach? Is there anything
>> obvious that would cause this problem, e.g. has anyone ran into this
>> before? Am I missing a sync? I'm about stumped.
>>
>> 2) Also under high load, I occasionally get this stack trace
>> (this is not the cause of or symptom of item 1, it is a separate
>> issue occurring at separate times)
>>
>> java.lang.NullPointerException:
>> (no message)
>> at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
>> at org.apache.xerces.dom.ParentNode.item(Unknown Source)
>> at freemarker.ext.dom.NodeListModel.<init>(NodeListModel.java:89)
>> at freemarker.ext.dom.NodeModel.getChildNodes(NodeModel.java:302)
>> at freemarker.ext.dom.ElementModel.get(ElementModel.java:124)
>> at freemarker.core.Dot._getAsTemplateModel(Dot.java:76)
>>
>> Again I'm suspecting thread safety and a missing sync. Just
>> refreshing the page works ok. I raised the issue with freemarker
>> since it's only their stack frames calling the DOM, so I figured the
>> burden falls on them to sync. But they passed the puck back to me
>> and said 'we do not guarantee thread safety if your data model is
>> not thread safe to begin with.' They're not going to go and add
>> sync blocks all over their code due to an implementation artifact of
>> your library, and I would agree with that. Really the lack of
>> thread safety even for reads is a pretty poor fit for a web
>> application... How do I fix this problem, in general is there a way
>> to make this library more thread safe? The best suggestion I have
>> for that stack trace so far is to use CGLib to proxy the element and
>> inject sync blocks where they should be. Ugh... https://
>> issues.apache.org/jira/browse/XERCESJ-727<http://issues.apache.org/jira/browse/XERCESJ-727> is relevant here
>>
>> What about calling documentBuilderFactory.setFeature("http://
>> apache.org/xml/features/dom/defer-node-expansion<http://apache.org/xml/features/dom/defer-node-expansion>", false); to turn
>> off lazy parsing? Does that guarantee thread safety since
>> everything is already parsed into ram and it's just read only?
>>
>>
>> Any input is very much appreciated, these issues are affecting
> production. K
>>
>> Thanks,
>> John
>

Re: DOM thread safety issues & disapearring children

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Alasdair,

gzunkal@googlemail.com wrote on 07/19/2011 05:48:30 PM:

> > While it may defy your intuition it isn't something that is
> guaranteed by the spec.
>
> To be fair, it's not just me... as you've pointed out, this question
> is perennial and you've been answering it for years :-)

Right. I didn't mean you specifically, but "one's intuition". :-)

There's a lot about DOM (and many other W3C specs for that matter) that
isn't intuitive. For example, (n instanceof Element) does not imply
(n.getNodeType() == Node.ELEMENT_NODE). Usually behaves how you'd expect
but no guarantee it will. Some node implementations implement multiple
interfaces (e.g. [1]).

> > In general JAXB objects are not guaranteed to be thread-safe
> either. In particular, DOM is used by default for representing
> wildcard content (i.e. unknown elements).
>
> I didn't know this, probably because the schema we used fully
> specified the documents, so the generated Java has been relatively
> clean and simple.
>
> Finally, I'd just like to thank you for your efforts over the years -
> I really do appreciate Xerces and what it's been able to do for me.

Thanks.

> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org

[1] http://markmail.org/message/ify2wid2ux355fqi

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

Re: DOM thread safety issues & disapearring children

Posted by Alasdair Thomson <al...@gzunk.com>.
> While it may defy your intuition it isn't something that is guaranteed by the spec.

To be fair, it's not just me... as you've pointed out, this question
is perennial and you've been answering it for years :-)

> In general JAXB objects are not guaranteed to be thread-safe either. In particular, DOM is used by default for representing wildcard content (i.e. unknown elements).

I didn't know this, probably because the schema we used fully
specified the documents, so the generated Java has been relatively
clean and simple.

Finally, I'd just like to thank you for your efforts over the years -
I really do appreciate Xerces and what it's been able to do for me.

---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


Re: DOM thread safety issues & disapearring children

Posted by David Lee <dl...@calldei.com>.
You may want to consider other XML document Apis
They may already do what you want with less effort

Xom
Saxon
Stax
...

Sent from my iPad (excuse the terseness) 
David A Lee
dlee@calldei.com


On Jul 19, 2011, at 11:06 PM, "Newman, John W" <ne...@d3onc.com> wrote:

> 
> Fair enough.  I do realize there's almost never motiviation  to do such difficult work without getting paid or any benefit to your own projects.  I did checkout the trunk and walk through the code earlier this afternoon.  I've got to say, it is a much larger project than I expected when I typed that [somewhat frustrated] last email.  It is not going to be trivial.  I apologize for my tone there, I did mean to delete some of that before sending and forgot.  :-)
> 
> A threadsafe extension for reads could be done though, I need a bit of time to get more familiar and see the the internal state in debug.  In the meantime it looks like i'm making OK progress patching the library that lacks the synchronization... But there's a voice in my head that says i'm just begging for a ton of deadlocks. I'm also beginning to actually consider a pooling solution in the interim, it would be the safest bet and just some easy spring xml changes...  I also am going to fragment the one document with 18 elements into 18 individual documents with one element.. that way the pools would be much smaller, and even if userA's got corrupt it's not the total end of the world as userB and userC can continue on.
> 
> 
> 
> 
> 
> ________________________________________
> From: Michael Glavassevich [mrglavas@ca.ibm.com]
> Sent: Tuesday, July 19, 2011 7:52 PM
> To: j-users@xerces.apache.org
> Subject: RE: DOM thread safety issues & disapearring children
> 
> Hi John,
> 
> "Newman, John W" <ne...@d3onc.com> wrote on 07/19/2011 02:15:20 PM:
> 
>> I’m not getting the reason why you cannot provide an extension that
>> syncs the internal writes just for the read only DOM methods.   To
>> allow thread safe reads particular to the implementation I know I am
>> using.  I do not expect arbitrary library swaps to work.. that is nonsense.
>> 
>> Would it really be that hard: search for references to the internal
>> state, for each reference, is the reference from a ‘read only’
>> method?  No-> do nothing, we know writes will still be volatile;
>> Yes -> override the method in the new extension, putting a sync
>> block using the touched internal field as the mutex…
>> 
>> performance should be fine, documents do not get corrupt from being
>> read twice, single threaded app guy doesn’t use it, everyone is happy.
> 
> To quote myself from 2007:
> 
> "... I think it's unlikely to happen for the same reasons for many things that don't happen in open source projects: limited resources which don't have enough interest (possibly in part because the community doesn't have enough interest) and/or time and/or capability to do the work."
> 
> Setting aside opinions of whether this should be done or not, throughout the years no one has ever volunteered to attempt this work. As long as that stays the case that would be the greatest reason it wouldn't happen.
> 
> Thanks.
> 
> Michael Glavassevich
> XML Parser Development
> IBM Toronto Lab
> E-mail: mrglavas@ca.ibm.com
> E-mail: mrglavas@apache.org
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
> For additional commands, e-mail: j-users-help@xerces.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


RE: DOM thread safety issues & disapearring children

Posted by "Newman, John W" <ne...@d3onc.com>.
Fair enough.  I do realize there's almost never motiviation  to do such difficult work without getting paid or any benefit to your own projects.  I did checkout the trunk and walk through the code earlier this afternoon.  I've got to say, it is a much larger project than I expected when I typed that [somewhat frustrated] last email.  It is not going to be trivial.  I apologize for my tone there, I did mean to delete some of that before sending and forgot.  :-)

A threadsafe extension for reads could be done though, I need a bit of time to get more familiar and see the the internal state in debug.  In the meantime it looks like i'm making OK progress patching the library that lacks the synchronization... But there's a voice in my head that says i'm just begging for a ton of deadlocks. I'm also beginning to actually consider a pooling solution in the interim, it would be the safest bet and just some easy spring xml changes...  I also am going to fragment the one document with 18 elements into 18 individual documents with one element.. that way the pools would be much smaller, and even if userA's got corrupt it's not the total end of the world as userB and userC can continue on.





________________________________________
From: Michael Glavassevich [mrglavas@ca.ibm.com]
Sent: Tuesday, July 19, 2011 7:52 PM
To: j-users@xerces.apache.org
Subject: RE: DOM thread safety issues & disapearring children

Hi John,

"Newman, John W" <ne...@d3onc.com> wrote on 07/19/2011 02:15:20 PM:

> I’m not getting the reason why you cannot provide an extension that
> syncs the internal writes just for the read only DOM methods.   To
> allow thread safe reads particular to the implementation I know I am
> using.  I do not expect arbitrary library swaps to work.. that is nonsense.
>
> Would it really be that hard: search for references to the internal
> state, for each reference, is the reference from a ‘read only’
> method?  No-> do nothing, we know writes will still be volatile;
> Yes -> override the method in the new extension, putting a sync
> block using the touched internal field as the mutex…
>
> performance should be fine, documents do not get corrupt from being
> read twice, single threaded app guy doesn’t use it, everyone is happy.

To quote myself from 2007:

"... I think it's unlikely to happen for the same reasons for many things that don't happen in open source projects: limited resources which don't have enough interest (possibly in part because the community doesn't have enough interest) and/or time and/or capability to do the work."

Setting aside opinions of whether this should be done or not, throughout the years no one has ever volunteered to attempt this work. As long as that stays the case that would be the greatest reason it wouldn't happen.

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: j-users-unsubscribe@xerces.apache.org
For additional commands, e-mail: j-users-help@xerces.apache.org


RE: DOM thread safety issues & disapearring children

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
Hi John,

"Newman, John W" <ne...@d3onc.com> wrote on 07/19/2011 02:15:20 PM:

> I?m not getting the reason why you cannot provide an extension that
> syncs the internal writes just for the read only DOM methods.   To
> allow thread safe reads particular to the implementation I know I am
> using.  I do not expect arbitrary library swaps to work.. that is
nonsense.
>
> Would it really be that hard: search for references to the internal
> state, for each reference, is the reference from a ?read only?
> method?  No-> do nothing, we know writes will still be volatile;
> Yes -> override the method in the new extension, putting a sync
> block using the touched internal field as the mutex?
>
> performance should be fine, documents do not get corrupt from being
> read twice, single threaded app guy doesn?t use it, everyone is happy.

To quote myself from 2007:

"... I think it's unlikely to happen for the same reasons for many things
that don't happen in open source projects: limited resources which don't
have enough interest (possibly in part because the community doesn't have
enough interest) and/or time and/or capability to do the work."

Setting aside opinions of whether this should be done or not, throughout
the years no one has ever volunteered to attempt this work. As long as that
stays the case that would be the greatest reason it wouldn't happen.

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

RE: DOM thread safety issues & disapearring children

Posted by "Newman, John W" <ne...@d3onc.com>.
I'm not getting the reason why you cannot provide an extension that syncs the internal writes just for the read only DOM methods.   To allow thread safe reads particular to the implementation I know I am using.  I do not expect arbitrary library swaps to work.. that is nonsense.

Would it really be that hard: search for references to the internal state, for each reference, is the reference from a 'read only' method?  No-> do nothing, we know writes will still be volatile;  Yes -> override the method in the new extension, putting a sync block using the touched internal field as the mutex...

performance should be fine, documents do not get corrupt from being read twice, single threaded app guy doesn't use it, everyone is happy.



From: Michael Glavassevich [mailto:mrglavas@ca.ibm.com]
Sent: Tuesday, July 19, 2011 1:49 PM
To: j-users@xerces.apache.org
Subject: RE: DOM thread safety issues & disapearring children


gzunkal@googlemail.com<ma...@googlemail.com> wrote on 07/19/2011 12:45:49 PM:

> I think the relevant complaint is that the DOM isn't thread safe for
> read-only operations, which is counter-intuitive unless you have
> knowledge of the underlying implementation. I don't think anyone
> expects it to be thread safe for updating.

While it may defy your intuition it isn't something that is guaranteed by the spec. If you expect your code to work with an arbitrary DOM implementation you must synchronize access for all operations.

> I've tended to use JAXB to transform the XML to java objects, which
> I can then make sure are thread safe for read only operations.

In general JAXB objects are not guaranteed to be thread-safe either. In particular, DOM is used by default for representing wildcard content (i.e. unknown elements).

> On Jul 19, 2011 5:26 PM, <ke...@us.ibm.com>> wrote:
> > In 99% of the use cases, locking the individual DOM objects/operations
> > would be the wrong level of granularity -- what you really need to prevent
> > unexpected results is transaction locking for a group of related changes.
> > That really does have to be done at the application level.
> >
> > Locking every individual operation also can have significant performance
> > impact, in these days of multikernel/multiprocessor machines, due to the
> > need to flush cache in order to make sure all the processors know the
> > lock's state has changed. The days of "synchronize is free" really are
> > over.
> >
> > Also, frankly, I would be reluctant to encourage people to rely on a
> > protected DOM since if/when they change platforms their code will break
> > unexpectedly.
> >
> > If you really want locks on every operation, you're free to build a
> > "threadsafe DOM manipulation" library which provides threadsafety -- eg
> > static Threadsafe.appendChild(Node parent, Node newChild). The code won't
> > look exactly like a simple DOM call, but in most JVMs this kind of simple
> > "tail call" is pretty efficient, it makes what you're doing explicit, and
> > it's portable to any DOM you care to throw at it.
> >
> >
> > ______________________________________
> > "You build world of steel and stone
> > I build worlds of words alone
> > Skilled tradespeople, long years taught:
> > You shape matter; I shape thought."
> > (http://www.songworm.com/lyrics/songworm-parody/ShapesofShadow.html)

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com<ma...@ca.ibm.com>
E-mail: mrglavas@apache.org<ma...@apache.org>

RE: DOM thread safety issues & disapearring children

Posted by Michael Glavassevich <mr...@ca.ibm.com>.
gzunkal@googlemail.com wrote on 07/19/2011 12:45:49 PM:

> I think the relevant complaint is that the DOM isn't thread safe for
> read-only operations, which is counter-intuitive unless you have
> knowledge of the underlying implementation. I don't think anyone
> expects it to be thread safe for updating.

While it may defy your intuition it isn't something that is guaranteed by
the spec. If you expect your code to work with an arbitrary DOM
implementation you must synchronize access for all operations.

> I've tended to use JAXB to transform the XML to java objects, which
> I can then make sure are thread safe for read only operations.

In general JAXB objects are not guaranteed to be thread-safe either. In
particular, DOM is used by default for representing wildcard content (i.e.
unknown elements).

> On Jul 19, 2011 5:26 PM, <ke...@us.ibm.com> wrote:
> > In 99% of the use cases, locking the individual DOM objects/operations
> > would be the wrong level of granularity -- what you really need to
prevent
> > unexpected results is transaction locking for a group of related
changes.
> > That really does have to be done at the application level.
> >
> > Locking every individual operation also can have significant
performance
> > impact, in these days of multikernel/multiprocessor machines, due to
the
> > need to flush cache in order to make sure all the processors know the
> > lock's state has changed. The days of "synchronize is free" really are
> > over.
> >
> > Also, frankly, I would be reluctant to encourage people to rely on a
> > protected DOM since if/when they change platforms their code will break

> > unexpectedly.
> >
> > If you really want locks on every operation, you're free to build a
> > "threadsafe DOM manipulation" library which provides threadsafety -- eg

> > static Threadsafe.appendChild(Node parent, Node newChild). The code
won't
> > look exactly like a simple DOM call, but in most JVMs this kind of
simple
> > "tail call" is pretty efficient, it makes what you're doing explicit,
and
> > it's portable to any DOM you care to throw at it.
> >
> >
> > ______________________________________
> > "You build world of steel and stone
> > I build worlds of words alone
> > Skilled tradespeople, long years taught:
> > You shape matter; I shape thought."
> > (http://www.songworm.com/lyrics/songworm-parody/ShapesofShadow.html)

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

RE: DOM thread safety issues & disapearring children

Posted by Alasdair Thomson <al...@gzunk.com>.
I think the relevant complaint is that the DOM isn't thread safe for
read-only operations, which is counter-intuitive unless you have knowledge
of the underlying implementation. I don't think anyone expects it to be
thread safe for updating.

I've tended to use JAXB to transform the XML to java objects, which I can
then make sure are thread safe for read only operations.
 On Jul 19, 2011 5:26 PM, <ke...@us.ibm.com> wrote:
> In 99% of the use cases, locking the individual DOM objects/operations
> would be the wrong level of granularity -- what you really need to prevent

> unexpected results is transaction locking for a group of related changes.
> That really does have to be done at the application level.
>
> Locking every individual operation also can have significant performance
> impact, in these days of multikernel/multiprocessor machines, due to the
> need to flush cache in order to make sure all the processors know the
> lock's state has changed. The days of "synchronize is free" really are
> over.
>
> Also, frankly, I would be reluctant to encourage people to rely on a
> protected DOM since if/when they change platforms their code will break
> unexpectedly.
>
> If you really want locks on every operation, you're free to build a
> "threadsafe DOM manipulation" library which provides threadsafety -- eg
> static Threadsafe.appendChild(Node parent, Node newChild). The code won't
> look exactly like a simple DOM call, but in most JVMs this kind of simple
> "tail call" is pretty efficient, it makes what you're doing explicit, and
> it's portable to any DOM you care to throw at it.
>
>
> ______________________________________
> "You build world of steel and stone
> I build worlds of words alone
> Skilled tradespeople, long years taught:
> You shape matter; I shape thought."
> (http://www.songworm.com/lyrics/songworm-parody/ShapesofShadow.html)
>
>
>
> From:
> "Newman, John W" <ne...@d3onc.com>
> To:
> "j-users@xerces.apache.org" <j-...@xerces.apache.org>
> Date:
> 07/19/2011 11:49 AM
> Subject:
> RE: DOM thread safety issues & disapearring children
>
>
>
> I just wanted to follow up and say that switching off deferred parsing did

> not add any stability. Still the same issues, same steps to reproduce
> everytime. And yes it is actually on, my elements did change from
> DeferredElementImpl to ElementImpl. So no dice there.
>
> Also setting the node to readonly didn’t work either, but I didn’t really
> expect it to since that’s for modifying the DOM and not clobbering the
> underlying unsafe state.
>
> Let me ask you this then .. since clearly there is an industry need for a
> thread safe document (like the one person said this comes up ALL the
> time), and you are pretty clear that the default implementation will
> always remain unsafe - “it’s up to the caller to add the locks”, why
> can’t you provide a simple extension of the current implementation that
> properly takes care of the syncing at a higher level but in-between the
> caller and the unsafe impl? Effectively do what I’m scrambling to do
> correctly and offload this burden…
>
> class ThreadSafeDeferredElementImpl extends DeferredElementImpl {
> @Override
> public void iAmNotTotallySureWhatMethodsNeedSycned() {
> synchronzized (this.something) {
> return this.something.whatever();
> }
> }
> }
>
> Isn’t that easy to do and win win? You can maintain your “it’s not thread
> safe stance”, and users that don’t require thread safety will still have
> the good performance, but users like us that essentially need to ditch
> your library can have the syncing properly taken care of and out of our
> code. Why not just do that?
>
> Thanks,
> John
>
>
>
> From: Michael Glavassevich [mailto:mrglavas@ca.ibm.com]
> Sent: Wednesday, June 08, 2011 12:06 AM
> To: j-users@xerces.apache.org
> Subject: Re: DOM thread safety issues & disapearring children
>
> Hi John,
>
> None of Xerces' DOM implementations are thread-safe, even the non-deferred

> ones. This is true even for read operations. In particular, the
> implementation of the NodeList methods (i.e. item() and getLength()) are
> not thread-safe. These methods do some internal writes to a cache which
> are necessary for good performance. There's a longer explanation in the
> JIRA issue you found.
>
> Thanks.
>
> Michael Glavassevich
> XML Parser Development
> IBM Toronto Lab
> E-mail: mrglavas@ca.ibm.com
> E-mail: mrglavas@apache.org
>
> "Newman, John W" <ne...@d3onc.com> wrote on 06/07/2011 04:17:22 PM:
>
>> All,
>>
>> My team has built a web application that has a few components that
>> rely heavily on the xerces DOM implementation. Unfortunately a lot
>> of this was developed before we even learned that the node
>> implementations are deliberately not thread safe. =) I’ve added a
>> few sync blocks where appropriate (I think), and everything is
>> functioning ok except for two remaining issues.
>>
>> 1) Under very high load, an element will somehow lose nearly
>> all of its children.
>> <root>
>> <ch0 />
>> <ch0 />
>> <ch0 />
>> <ch1 />
>> <ch1 />
>> <ch2><ch2.1 /></ch2>
>> <ch3><ch3.1><ch3.2 /></ch3.1></ch3>
>> …. Rather large document, many levels of nesting
>> </root>
>>
>> That will sit there and work fine for a few days, until something
>> (?) happens and most of the children will disappear . I cannot
>> isolate this problem at all, it has been very difficult to track
>> anything down so I’m asking for help. There are no exceptions in
>> the log or anything otherwise to indicate that something bad is
>> happening. One day I saw
>>
>> <root>
>> <ch0 />
>> <ch0 />
>> </root>
>>
>> And then a few days later
>>
>> <root>
>> <ch0 />
>> <ch0 />
>> <ch0 />
>> <ch1 />
>> </root>
>>
>> The fact that there doesn’t seem to be any pattern to which children
>> stay vs. which disappear, and only under higher load has me
>> suspecting thread safety. In general it seems like the smaller
>> elements at the top are more likely to hang around, but again
>> there’s no real pattern. We are not doing any modification on these
>> nodes, in fact I want to make them read only. I’m debating on
>> casting the org.w3c.Node to org.apache.xerces.dom.NodeImpl and
>> calling setReadOnly(true, true) on it to freeze it – but the
>> javadoc says I probably shouldn’t need that method? If I did that,
>> I’d at least get a stack trace when whatever it is decides to modify
>> it. Does that sound like a good approach? Is there anything
>> obvious that would cause this problem, e.g. has anyone ran into this
>> before? Am I missing a sync? I’m about stumped.
>>
>> 2) Also under high load, I occasionally get this stack trace
>> (this is not the cause of or symptom of item 1, it is a separate
>> issue occurring at separate times)
>>
>> java.lang.NullPointerException:
>> (no message)
>> at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source)
>> at org.apache.xerces.dom.ParentNode.item(Unknown Source)
>> at freemarker.ext.dom.NodeListModel.<init>(NodeListModel.java:89)
>> at freemarker.ext.dom.NodeModel.getChildNodes(NodeModel.java:302)
>> at freemarker.ext.dom.ElementModel.get(ElementModel.java:124)
>> at freemarker.core.Dot._getAsTemplateModel(Dot.java:76)
>>
>> Again I’m suspecting thread safety and a missing sync. Just
>> refreshing the page works ok. I raised the issue with freemarker
>> since it’s only their stack frames calling the DOM, so I figured the
>> burden falls on them to sync. But they passed the puck back to me
>> and said ‘we do not guarantee thread safety if your data model is
>> not thread safe to begin with.’ They’re not going to go and add
>> sync blocks all over their code due to an implementation artifact of
>> your library, and I would agree with that. Really the lack of
>> thread safety even for reads is a pretty poor fit for a web
>> application... How do I fix this problem, in general is there a way
>> to make this library more thread safe? The best suggestion I have
>> for that stack trace so far is to use CGLib to proxy the element and
>> inject sync blocks where they should be. Ugh… https://
>> issues.apache.org/jira/browse/XERCESJ-727 is relevant here
>>
>> What about calling documentBuilderFactory.setFeature("http://
>> apache.org/xml/features/dom/defer-node-expansion", false); to turn
>> off lazy parsing? Does that guarantee thread safety since
>> everything is already parsed into ram and it’s just read only?
>>
>>
>> Any input is very much appreciated, these issues are affecting
> production. K
>>
>> Thanks,
>> John
>

RE: DOM thread safety issues & disapearring children

Posted by ke...@us.ibm.com.
In 99% of the use cases, locking the individual DOM objects/operations 
would be the wrong level of granularity -- what you really need to prevent 
unexpected results is transaction locking for a group of related changes. 
That really does have to be done at the application level.

Locking every individual operation also can have significant performance 
impact, in these days of multikernel/multiprocessor machines, due to the 
need to flush cache in order to make sure all the processors know the 
lock's state has changed. The days of "synchronize is free" really are 
over.

Also, frankly, I would be reluctant to encourage people to rely on a 
protected DOM since if/when they change platforms their code will break 
unexpectedly.

If you really want locks on every operation, you're free to build a 
"threadsafe DOM manipulation" library which provides threadsafety -- eg 
static Threadsafe.appendChild(Node parent, Node newChild). The code won't 
look exactly like a simple DOM call, but in most JVMs this kind of simple 
"tail call" is pretty efficient, it makes what you're doing explicit, and 
it's portable to any DOM you care to throw at it.


______________________________________
"You build world of steel and stone
I build worlds of words alone
Skilled tradespeople, long years taught:
You shape matter; I shape thought."
(http://www.songworm.com/lyrics/songworm-parody/ShapesofShadow.html)



From:
"Newman, John W" <ne...@d3onc.com>
To:
"j-users@xerces.apache.org" <j-...@xerces.apache.org>
Date:
07/19/2011 11:49 AM
Subject:
RE: DOM thread safety issues & disapearring children



I just wanted to follow up and say that switching off deferred parsing did 
not add any stability.  Still the same issues, same steps to reproduce 
everytime.  And yes it is actually on, my elements did change from 
DeferredElementImpl to ElementImpl.  So no dice there. 
 
Also setting the node to readonly didn’t work either, but I didn’t really 
expect it to since that’s for modifying the DOM and not clobbering the 
underlying unsafe state.
 
Let me ask you this then .. since clearly there is an industry need for a 
thread safe document (like the one person said this comes up ALL the 
time), and you are pretty clear that the default implementation will 
always remain unsafe - “it’s up to the caller to add the locks”,  why 
can’t you provide a simple extension of the current implementation that 
properly takes care of the syncing at a higher level but in-between the 
caller and the unsafe impl?  Effectively do what I’m scrambling to do 
correctly and offload this burden…
 
class  ThreadSafeDeferredElementImpl extends DeferredElementImpl  {
   @Override
   public void iAmNotTotallySureWhatMethodsNeedSycned()  {
      synchronzized (this.something)  {
         return this.something.whatever();
      }
  }
}
 
Isn’t that easy to do and win win?  You can maintain your “it’s not thread 
safe stance”, and users that don’t require thread safety will still have 
the good performance, but users like us that essentially need to ditch 
your library can have the syncing properly taken care of and out of our 
code.  Why not just do that?
 
Thanks,
John
 
 
 
From: Michael Glavassevich [mailto:mrglavas@ca.ibm.com] 
Sent: Wednesday, June 08, 2011 12:06 AM
To: j-users@xerces.apache.org
Subject: Re: DOM thread safety issues & disapearring children
 
Hi John,

None of Xerces' DOM implementations are thread-safe, even the non-deferred 
ones. This is true even for read operations. In particular, the 
implementation of the NodeList methods (i.e. item() and getLength()) are 
not thread-safe. These methods do some internal writes to a cache which 
are necessary for good performance. There's a longer explanation in the 
JIRA issue you found.

Thanks.

Michael Glavassevich
XML Parser Development
IBM Toronto Lab
E-mail: mrglavas@ca.ibm.com
E-mail: mrglavas@apache.org

"Newman, John W" <ne...@d3onc.com> wrote on 06/07/2011 04:17:22 PM:

> All,
> 
> My team has built a web application that has a few components that 
> rely heavily on the xerces DOM implementation.  Unfortunately a lot 
> of this was developed before we even learned that the node 
> implementations are deliberately not thread safe. =)  I’ve added a 
> few sync blocks where appropriate (I think), and everything is 
> functioning ok except for two remaining issues. 
> 
> 1)      Under very high load, an element will somehow lose nearly 
> all of its children.
> <root>
>   <ch0 />
>   <ch0 />
>   <ch0 />
>   <ch1 />
>   <ch1 />
>   <ch2><ch2.1 /></ch2>
>   <ch3><ch3.1><ch3.2 /></ch3.1></ch3>
>   …. Rather large document, many levels of nesting
> </root>
> 
> That will sit there and work fine for a few days, until something 
> (?) happens and most of the children will disappear .  I cannot 
> isolate this problem at all, it has been very difficult to track 
> anything down so I’m asking for help.  There are no exceptions in 
> the log or anything otherwise to indicate that something bad is 
> happening.  One day I saw
> 
> <root>
>   <ch0 />
>   <ch0 />
> </root>
> 
> And then a few days later
> 
> <root>
>   <ch0 />
>   <ch0 />
>   <ch0 />
>   <ch1 />
> </root>
> 
> The fact that there doesn’t seem to be any pattern to which children
> stay vs. which disappear, and only under higher load has me 
> suspecting thread safety.  In general it seems like the smaller 
> elements at the top are more likely to hang around, but again 
> there’s no real pattern.  We are not doing any modification on these
> nodes, in fact I want to make them read only.  I’m debating on 
> casting the org.w3c.Node to org.apache.xerces.dom.NodeImpl and 
> calling setReadOnly(true, true)  on it to freeze it – but the 
> javadoc says I probably shouldn’t need that method?  If I did that, 
> I’d at least get a stack trace when whatever it is decides to modify
> it.  Does that sound like a good approach?  Is there anything 
> obvious that would cause this problem, e.g. has anyone ran into this
> before?  Am I missing a sync?  I’m about stumped.
> 
> 2)       Also under high load, I occasionally get this stack trace 
> (this is not the cause of or symptom of item 1, it is a separate 
> issue occurring at separate times)
> 
> java.lang.NullPointerException: 
> (no message) 
> at org.apache.xerces.dom.ParentNode.nodeListItem(Unknown Source) 
> at org.apache.xerces.dom.ParentNode.item(Unknown Source) 
> at freemarker.ext.dom.NodeListModel.<init>(NodeListModel.java:89) 
> at freemarker.ext.dom.NodeModel.getChildNodes(NodeModel.java:302) 
> at freemarker.ext.dom.ElementModel.get(ElementModel.java:124) 
> at freemarker.core.Dot._getAsTemplateModel(Dot.java:76) 
> 
> Again I’m suspecting thread safety and a missing sync.    Just 
> refreshing the page works ok.  I raised the issue with freemarker 
> since it’s only their stack frames calling the DOM, so I figured the
> burden falls on them to sync.  But they passed the puck back to me 
> and said ‘we do not guarantee thread safety if your data model is 
> not thread safe to begin with.’  They’re not going to go and add 
> sync blocks all over their code due to an implementation artifact of
> your library, and I would agree with that.  Really the lack of 
> thread safety even for reads is a pretty poor fit for a web 
> application...  How do I fix this problem, in general is there a way
> to make this library more thread safe?  The best suggestion I have 
> for that stack trace so far is to use CGLib to proxy the element and
> inject sync blocks where they should be.  Ugh…  https://
> issues.apache.org/jira/browse/XERCESJ-727 is relevant here
> 
> What about calling documentBuilderFactory.setFeature("http://
> apache.org/xml/features/dom/defer-node-expansion", false);   to turn
> off lazy parsing?  Does that guarantee thread safety since 
> everything is already parsed into ram and it’s just read only?
> 
> 
> Any input is very much appreciated, these issues are affecting 
production.  K
> 
> Thanks,
> John