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
Closed

Enum#valueOf thread safety issue #2014

pierre opened this issue Sep 30, 2014 · 1 comment

Comments

@pierre
Copy link

pierre 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
Copy link
Member

kares 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
…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
…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
…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
…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
…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
…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
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
* 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 as completed Feb 27, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants