10

I have some Vaadin code blocking very often here, and I have no idea what the problem can be:

Thread 7892: (state = IN_JAVA)
 - java.util.HashMap.getEntry(java.lang.Object) @bci=61, line=349 (Compiled frame; information may be imprecise)
 - java.util.HashMap.containsKey(java.lang.Object) @bci=2, line=335 (Compiled frame)
 - java.util.HashSet.contains(java.lang.Object) @bci=5, line=184 (Compiled frame)
 - com.vaadin.ui.Table.unregisterPropertiesAndComponents(java.util.HashSet, java.util.HashSet) @bci=85, line=1693 (Compiled frame)
 - com.vaadin.ui.Table.refreshRenderedCells() @bci=992, line=1641 (Compiled frame)
 - com.vaadin.ui.Table.valueChange(com.vaadin.data.Property$ValueChangeEvent) @bci=23, line=2897 (Compiled frame)
 - com.vaadin.data.util.IndexedContainer.firePropertyValueChange(com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=140, line=553 (Compiled frame)
 - com.vaadin.data.util.IndexedContainer.access$1000(com.vaadin.data.util.IndexedContainer, com.vaadin.data.util.IndexedContainer$IndexedContainerProperty) @bci=2, line=64 (Compiled frame)
 - com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(java.lang.Object) @bci=202, line=915 (Compiled frame)
 - com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread.insertNewPersonIntoTable(com.aimprosoft.wavilon.model.Person, com.vaadin.ui.HorizontalLayout, com.aimprosoft.wavilon.ui.menuitems.CallContent, com.vaadin.ui.Table) @bci=924, line=208 (Interpreted frame)
 - com.aimprosoft.wavilon.backgroundthreads.ChangeCdrThread$RepaintTableThread.run() @bci=622, line=446 (Compiled frame)

Can somebody suggest any way to further debug this issue? The problem happens very rarely, and it is quite difficult to reproduce.

Boann
  • 48,794
  • 16
  • 117
  • 146
blueFast
  • 41,341
  • 63
  • 198
  • 344
  • can you get some piece of source code ? – iMysak Apr 18 '12 at 23:54
  • In this case there is no need for actual source code. I've seen this stack trace often enough. :) – Roland Illig Apr 18 '12 at 23:57
  • @gonvaled Please take a look at my answer, it explains in detail why you see this behavior. – John Vint Apr 19 '12 at 20:52
  • Failed to find this bug in [vaadin issue tracker](http://dev.vaadin.com/search?q=infinite+loop+hashmap&noquickjump=1&ticket=on&changeset=on&milestone=on&wiki=on). It seems it's still there in recent version. Member `HashSet`'s aren't synchronized: http://grepcode.com/file/repo1.maven.org/maven2/com.vaadin/vaadin-server/7.1.11/com/vaadin/ui/Table.java#464 – Vadzim May 20 '14 at 09:56

3 Answers3

17

Based on where it is in the code, the only explanation I can think of is that there are multiple threads accessing and updating that HashMap without synchronizing properly. This can cause the map's data structures to be corrupted, and could result in an infinite loop.

I can't think of any other reason why java.util.HashMap.getEntry would block. It doesn't do any synchronization or any I/O.


Roland Illig comments:

The line number indeed suggests that the code hangs in one of the e = e.next loops.

That supports my hypothesis. A particular sequence of operations on the hash table performed by two (or more) threads has resulted in the creation of a loop / cycle in one of the hash chains. This corruption has happened because there was inadequate synchronization between the threads performing the operations. It is the kind of thing that happens very rarely, but once it has happened the corruption won't go away.

Without looking deeply into the Vaadin source code, I can't tell you exactly whether it is a Vaadin bug, or a bug in the way that you are using Vaadin. Either explanation is plausible.

UPDATE

Based on this article (provided in a comment below), I would say that it is most likely a problem in the way that your application is synchronizing (or not).

SOS
  • 6,430
  • 2
  • 11
  • 29
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    The line number indeed suggests that the code hangs in one of the `e = e.next` loops. – Roland Illig Apr 18 '12 at 23:55
  • You are indeed right that my formulation is a bit contradictory. What I meant is: it is *very difficult* to reproduce (I have to generate lots of data to stress test, and click around my web application randomly to make this happen), but whenever it reaches an error situation, *very often* it is showing the shown stack trace. Sorry for my sloppiness, but yesterday after a long debug day I was feeling a bit frustrated. – blueFast Apr 19 '12 at 08:09
9

So what you are actually seeing here is a thread going into an infinite loop evaluating e = e.next

In essence

e.next == e

This occurs when you are putting into a HashMap by multiple threads during a table restructure.

Take a look at this link for more information

A Beautiful Race Condition

To solve this either use a Collections.synchronizedMap or ConcurrentHashMap. I suggest the latter.

John Vint
  • 39,695
  • 7
  • 78
  • 108
  • Unfortunately I can not change the implementation of the vaadin libraries (well, I suppose I could, but that would be much too complicated) – blueFast Apr 19 '12 at 21:09
  • @gonvaled Are they on github? You can open a pull request, or maybe there is a newer version with a fix in. – John Vint Apr 19 '12 at 21:11
2

Is your background thread synchronized on the application instance when modifying the component? If not, then that is your problem.

Artur
  • 21
  • 1
  • @gonvaled As Artur is saying you *must* synchronize your background processing to the Vaadin appliction instance or you will run into problems like this. See this article: http://njbartlett.name/2011/05/25/concurrent-vaadin.html for a solution and example code. – hezamu Apr 23 '12 at 07:36