[jdom-interest] Namespace threading bug

Joe Bowbeer joe.bowbeer at gmail.com
Tue Dec 16 15:07:58 PST 2008


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) { ... }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.jdom.org/pipermail/jdom-interest/attachments/20081216/dd5c026b/attachment.htm


More information about the jdom-interest mailing list