[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