Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enum#valueOf thread safety issue #2014

Closed
pierre opened this Issue Sep 30, 2014 · 1 comment

Comments

Projects
None yet
2 participants
@pierre
Copy link

commented Sep 30, 2014

The following snippet sometimes throws ArgumentError: wrong number of arguments (1 for 2):

threads = (0..5).map do
  Thread.new { Java::java.util.concurrent.TimeUnit.value_of('NANOSECONDS') }
end

threads.each { |thread| thread.join }

Raw compiled trace (-Xbacktrace.style=raw):

ArgumentError: wrong number of arguments (1 for 2)
         getStackTrace at java/lang/Thread.java:1589
      getBacktraceData at org/jruby/runtime/backtrace/TraceType.java:175
          getBacktrace at org/jruby/runtime/backtrace/TraceType.java:39
      prepareBacktrace at org/jruby/RubyException.java:223
              preRaise at org/jruby/exceptions/RaiseException.java:213
              preRaise at org/jruby/exceptions/RaiseException.java:194
                <init> at org/jruby/exceptions/RaiseException.java:110
     newRaiseException at org/jruby/Ruby.java:3889
      newArgumentError at org/jruby/Ruby.java:3402
  findCallableArityOne at org/jruby/java/invokers/RubyToJavaInvoker.java:265
                  call at org/jruby/java/invokers/StaticMethodInvoker.java:56
                  call at org/jruby/internal/runtime/methods/AliasMethod.java:69
          cacheAndCall at org/jruby/runtime/callsite/CachingCallSite.java:334
                  call at org/jruby/runtime/callsite/CachingCallSite.java:185
           processCall at org/jruby/ir/interpreter/Interpreter.java:307
             interpret at org/jruby/ir/interpreter/Interpreter.java:564
       INTERPRET_BLOCK at org/jruby/ir/interpreter/Interpreter.java:659
       commonYieldPath at org/jruby/runtime/InterpretedIRBlockBody.java:50
                  call at org/jruby/runtime/IRBlockBody.java:67
                  call at org/jruby/runtime/Block.java:106
                  call at org/jruby/RubyProc.java:301
                  call at org/jruby/RubyProc.java:230
                   run at org/jruby/internal/runtime/RubyRunnable.java:99
                   run at java/lang/Thread.java:745

Adding a trace in RubyToJavaInvoker#findCallableArityOne, the looked up method is:

public static java.lang.Enum java.lang.Enum.valueOf(java.lang.Class,java.lang.String)

Tested both on JRuby 1.7.11 and 1.7.16.

@kares

This comment has been minimized.

Copy link
Member

commented Oct 13, 2014

work-aroud is to use the following for now :

Java::JavaLang::Enum.value_of(java.util.concurrent.TimeUnit.java_class, 'NANOSECONDS')

than

threads = (0..5).map do
  Thread.new { Java::JavaLang::Enum.value_of(java.util.concurrent.TimeUnit.java_class, 'NANOSECONDS') }
end

threads.each { |thread| thread.join }

"only" prints as warnings which is due a concurrent initialization of the wrapper class :
.../jruby.jar!/jruby/java/java_package_module_template.rb:14 warning: already initialized constant JavaUtilConcurrent

this (while still a valid JRuby issue) can be avoided when the class is initialized before hand e.g. :

Java::JavaUtilConcurrent::TimeUnit

threads = (0..5).map do
  Thread.new { Java::JavaLang::Enum.value_of(java.util.concurrent.TimeUnit.java_class, 'NANOSECONDS') }
end

threads.each { |thread| thread.join }

kares added a commit to kares/jruby that referenced this issue Feb 3, 2015

guard against concurrent Java:: package module initializations (in mu…
…ltiple threads)

avoid warnings such as rb:42 warning: already initialized constant JavaUtilConcurrent

probably related to jruby#2014

kares added a commit to kares/jruby that referenced this issue Feb 4, 2015

guard against concurrent Java:: package module initializations (in mu…
…ltiple threads)

avoid warnings such as rb:42 warning: already initialized constant JavaUtilConcurrent

probably related to jruby#2014

kares added a commit to kares/jruby that referenced this issue Feb 4, 2015

guard against concurrent Java:: package module initializations (in mu…
…ltiple threads)

avoid warnings such as rb:42 warning: already initialized constant JavaUtilConcurrent

probably related to jruby#2014

kares added a commit to kares/jruby that referenced this issue Feb 4, 2015

guard against concurrent Java:: package module initializations (in mu…
…ltiple threads)

avoid warnings such as rb:42 warning: already initialized constant JavaUtilConcurrent

probably related to jruby#2014

kares added a commit to kares/jruby that referenced this issue Feb 6, 2015

guard against concurrent Java:: package module initializations (in mu…
…ltiple threads)

avoid warnings such as rb:42 warning: already initialized constant JavaUtilConcurrent

probably related to jruby#2014

kares added a commit to kares/jruby that referenced this issue Feb 27, 2015

for now - locking same proxy class resolution from multiple threads (…
…this fixes jruby#2014)

... triggered from JavaPackageModuleTemplate's const_get invocation end currently ends up as `JavaUtilities.get_proxy_class` call

... more work might be suitable to avoid the lock on places where it's likely redundant

kares added a commit to kares/jruby that referenced this issue Feb 27, 2015

headius added a commit that referenced this issue Feb 27, 2015

Contract of ClassValue states it should only calculate once.
This appears to help avoid issues with multiple or partially-
initialized proxies as in #2014.

headius added a commit that referenced this issue Feb 27, 2015

Cleanup, reduce duplication, refactor methods for proxy creation.
* Java.getProxyClass is the one true way to get the Ruby proxy
  class for a Java class.
* Unified more of class vs interface proxy logic.
* Both #1621 and #2014 appear to be working with this commit.

@kares kares added this to the JRuby 1.7.20 milestone Feb 27, 2015

kares added a commit that referenced this issue Feb 27, 2015

@kares kares closed this Feb 27, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.