You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by "Niall Pemberton (JIRA)" <ji...@apache.org> on 2007/01/05 05:50:27 UTC
[jira] Updated: (JXPATH-2) [jxpath] Using JXPath in multiple
threads
[ https://issues.apache.org/jira/browse/JXPATH-2?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Niall Pemberton updated JXPATH-2:
---------------------------------
Fix Version/s: 1.3
> [jxpath] Using JXPath in multiple threads
> -----------------------------------------
>
> Key: JXPATH-2
> URL: https://issues.apache.org/jira/browse/JXPATH-2
> Project: Commons JXPath
> Issue Type: Bug
> Environment: Operating System: All
> Platform: All
> Reporter: Robert Sax
> Fix For: 1.3
>
>
> I was unable to determine if JXPath was intended to be used concurrently or not,
> but after using it in a server application that runs 100+ threads concurrently,
> I started getting errors (they were rare) that showed the following trace:
> java.lang.NullPointerException
> at
> org.apache.commons.jxpath.ri.model.beans.BeanPropertyPointer.getPropertyNames(BeanPropertyPointer.java:72)
> at
> org.apache.commons.jxpath.ri.model.beans.PropertyIterator.prepareForIndividualProperty(PropertyIterator.java:248)
> at
> org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPositionIndividualProperty(PropertyIterator.java:141)
> at
> org.apache.commons.jxpath.ri.model.beans.PropertyIterator.setPosition(PropertyIterator.java:127)
> at
> org.apache.commons.jxpath.ri.axes.ChildContext.setPosition(ChildContext.java:106)
> at org.apache.commons.jxpath.ri.axes.ChildContext.nextNode(ChildContext.java:89)
> at org.apache.commons.jxpath.ri.EvalContext.nextSet(EvalContext.java:322)
> at org.apache.commons.jxpath.ri.axes.UnionContext.setPosition(UnionContext.java:55)
> at
> org.apache.commons.jxpath.ri.axes.NodeSetContext.nextNode(NodeSetContext.java:64)
> at org.apache.commons.jxpath.ri.EvalContext.constructIterator(EvalContext.java:181)
> at org.apache.commons.jxpath.ri.EvalContext.hasNext(EvalContext.java:114)
> at
> com.paychex.hrs.ei.conversion.jaxb.InboundProcessor.process(InboundProcessor.java:136)
> The code calling has next looks like:
> Iterator oIter = m_oIdentifier.iteratePointers(oXCtx);
> >>> while (oIter.hasNext())
> {
> The application has 100 worker threads, each processing the same
> message(converted to beans by JAXB), but different instances of it. This error
> occurs infrequently - happening only about once every 3 runs (each run processes
> 1000 messages). I performed the test on a P4/Windows box, but I believe that
> this is independent of os/system.
> I believe I have found some of the source code that may be causing this. It
> appears that bean info is stored in an internal cache (JXPathIntrospector) that
> all threads would end up using. For this to be thread safe, JXPathIntrospector
> needs to be thread safe (which it is even though synchronization is not used),
> and JXPathBasicBeanInfo needs to be thread safe (it is not). Basically what is
> happening is that inside of JXPathBasicBeanInfo, a couple of procedures build
> member variables on demand. However this demand based building is not thread
> safe and so a race condition exists between multiple threads that are both
> performing the on demand building. Specifically getPropertyDescriptors and
> getPropertyDescriptor modify propertyDescriptors and propertyNames in an unsafe
> manner. Either synchronization should be used or the assignment to the member
> variable should be performed last (resulting in duplicate effort but thread
> safety). Here are the pieces of code I am referring to:
> public PropertyDescriptor[] getPropertyDescriptors() {
> if (propertyDescriptors == null) {
> try {
> BeanInfo bi = null;
> if (clazz.isInterface()) {
> bi = Introspector.getBeanInfo(clazz);
> }
> else {
> bi = Introspector.getBeanInfo(clazz, Object.class);
> }
> PropertyDescriptor[] pds = bi.getPropertyDescriptors();
> propertyDescriptors = new PropertyDescriptor[pds.length];
> // At this point, the cache of property descriptors has been cleared possibly
> // conflicting with other threads
> System.arraycopy(pds, 0, propertyDescriptors, 0, pds.length);
> Arrays.sort(propertyDescriptors, new Comparator() {
> public int compare(Object left, Object right) {
> return ((PropertyDescriptor) left).getName().compareTo(
> ((PropertyDescriptor) right).getName());
> }
> });
> }
> ...
> public PropertyDescriptor getPropertyDescriptor(String propertyName) {
> if (propertyNames == null) {
> PropertyDescriptor[] pds = getPropertyDescriptors();
> propertyNames = new String[pds.length];
> // At this point the property names has been cleared possibly conflicting with
> // other threads
> for (int i = 0; i < pds.length; i++) {
> propertyNames[i] = pds[i].getName();
> }
> }
> Thanks,
> Rob Sax
--
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