In JavaObject.wrap(...) a RubyObject is created which corresponds to an instance of a java object. The java instance is currently used to synchronize access to the cached RubyObjects.
Synchronizing on the java instance can be inherently dangerous due to the common practice in java of declaring public methods synchronized and using non-private instances for synchronized blocks.
This problem has affected our development of a desktop application when using the Batik library through jruby. One of the classes which is a part of their public API followed the practice described above of using publicly available objects as a monitor for synchronization. The combination of that practice and the way JavaObject.wrap was locking on the same java instance caused periodic deadlock in our application.
I've included a patch and a small sample project with a test case which results in deadlock with the current JavaObject.wrap implementation and successfully runs to completion with the patch applied. The patch synchronizes on the JavaObject wrapper instance instead of the java instance.
To run the test from within the included project:
rake test jruby=path/to/jruby
JRUBY-199(and related) that eliminates this synchronization, among other things. (It actually eliminates the cache in question, replacing it elsewhere with a cache of proxy instances. See my old note from 28 June atJRUBY-199; I'm pretty much following the scheme I laid out there.) Will get this in in the next day or so.