[jdom-interest] Namespace threading bug

Eric Burke burke.eric at gmail.com
Tue Dec 16 16:33:58 PST 2008


Yes, that's exactly right.

On Tue, Dec 16, 2008 at 5:07 PM, Joe Bowbeer <joe.bowbeer at gmail.com> wrote:

> This is different from the design decision that JDOM documents are not
> threadsafe, right?  Because one namespace cache is used by all documents?
>
> Does JDOM cache any other objects in this manner?
>
> By the way, in Java 5 a ConcurrentHashMap would be more efficient than a
> synchronized HashMap.
>
> Joe
>
>
> On Tue, Dec 16, 2008 at 1:12 PM, Eric Burke wrote:
>
>> Hi,
>>
>> Our application uses JDOM (along with ROME), and spawns several threads to
>> download RSS feeds. We utilize ROME custom modules, which use JDOM Namespace
>> support. Sometimes, perhaps 1 in 15 launches, the XML parsing never
>> finishes. Instead, all 4 cores on my machine are 100% loaded as
>> HashMap.get() loops infinitely.
>>
>> We tracked this down to the org.jdom.Namespace class. It has an
>> "interesting" comment:
>>
>>     // XXX We may need to make the namespaces HashMap synchronized with
>>     // reader/writer locks or perhaps make Namespace no longer a
>> flyweight.
>>     // As written, multiple put() calls may happen from different threads
>>     // concurrently and cause a ConcurrentModificationException. See
>>     //
>> http://lists.denveronline.net/lists/jdom-interest/2000-September/003009.html
>> .
>>     // No one has ever reported this over the many years, so don't worry
>> yet.
>>
>> Well, I'm reporting it. It does not cause ConcurrentModificationException,
>> however. Instead, the map becomes corrupt and get() loops infinitely. Here
>> is a stack trace from a thread dump taken using Sun's VisualVM:
>>
>> "SwingWorker-pool-4-thread-1" prio=6 tid=0x11d1c800 nid=0x5c8 runnable
>> [0x1186f000..0x1186fc68]
>>    java.lang.Thread.State: RUNNABLE
>>     at java.util.HashMap.get(Unknown Source)
>>     at org.jdom.Namespace.getNamespace(Namespace.java:148)
>>     at org.jdom.Namespace.getNamespace(Namespace.java:202)
>>     at
>> com.sun.syndication.io.impl.ModuleParsers.parseModules(ModuleParsers.java:49)
>>     at
>> com.sun.syndication.io.impl.BaseWireFeedParser.parseFeedModules(BaseWireFeedParser.java:53)
>>     at
>> com.sun.syndication.io.impl.Atom10Parser.parseFeed(Atom10Parser.java:177)
>>     at
>> com.sun.syndication.io.impl.Atom10Parser.parse(Atom10Parser.java:75)
>>     at com.sun.syndication.io.WireFeedInput.build(WireFeedInput.java:252)
>>     at com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:161)
>>     at
>> coop.nisc.newsreader.impl.rome.RomeFeedProvider.getFeedFromAtom(RomeFeedProvider.java:87)
>>     at coop.nisc.newsreader.impl.XmlIo.getEntriesFromXml(XmlIo.java:205)
>>     at
>> coop.nisc.newsreader.impl.FileDataStore.loadFromDisk(FileDataStore.java:51)
>>     at
>> coop.nisc.newsreader.impl.FileDataStore.getViewEntries(FileDataStore.java:41)
>>     - locked <0x0508ae58> (a coop.nisc.newsreader.impl.FileDataStore)
>>     at
>> coop.nisc.newsreader.SubscriptionModel$GetInitialEntriesWorker.doInBackground(SubscriptionModel.java:331)
>>     at
>> coop.nisc.newsreader.SubscriptionModel$GetInitialEntriesWorker.doInBackground(SubscriptionModel.java:326)
>>     at javax.swing.SwingWorker$1.call(Unknown Source)
>>     at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
>>     at java.util.concurrent.FutureTask.run(Unknown Source)
>>     at javax.swing.SwingWorker.run(Unknown Source)
>>     at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown
>> Source)
>>     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
>>     at java.lang.Thread.run(Unknown Source)
>>
>> The app hangs on that HashMap.get() forever, as it loops infinitely,
>> consuming all CPU.
>>
>> The JDOM bug is that Namespace.java reads and writes to/from the HashMap
>> class (private static HashMap namespaces;) without proper synchronization.
>> Failure to synchronize on a HashMap is a well-known threading bug:
>>
>> http://lightbody.net/blog/2005/07/hashmapget_can_cause_an_infini.html
>>
>>
>> I don't have a small test case (yet), but from a code review it looks as
>> if synchronizing this method in Namespace.java will solve the issue:
>>
>> public static Namespace getNamespace(String prefix, String uri) { ... }
>>
>
>
> _______________________________________________
> To control your jdom-interest membership:
> http://www.jdom.org/mailman/options/jdom-interest/youraddr@yourhost.com
>



-- 
Eric M. Burke
http://www.linkedin.com/in/ericburke
314-494-3185 (mobile)
636-272-3298 (home)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.jdom.org/pipermail/jdom-interest/attachments/20081216/8f5c5d2a/attachment.htm


More information about the jdom-interest mailing list