Skip to content

invokedynamic makes Concurrent::TimerTask.execute reliably result in java.lang.invoke.WrongMethodTypeException  #7904

@yaauie

Description

@yaauie

Environment Information

Provide at least:

  • JRuby version (jruby -v) and command line (flags, JRUBY_OPTS, etc)
    • jruby 9.4.3.0 (3.1.4) 2023-06-07 3086960792 OpenJDK 64-Bit Server VM 20.0.1+9-29 on 20.0.1+9-29 +indy +jit [arm64-darwin]
      
    • jruby -d

    • JRUBY_OPTS="-Xcompile.invokedynamic=true -Xjit.threshold=0"
      
      
  • Operating system and platform (e.g. uname -a)
    • Darwin maybe.lan 22.6.0 Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000 arm64
      

Other relevant info you may wish to add:

  • Installed or activated gems:
    • concurrent-ruby: (replicates with 1.1.9, 1.2.2)
  • Application/framework version (e.g. Rails, Sinatra):
    • None
  • Environment variables:
    • nothing relevant beyond the JRUBY_OPTS mentioned above

Thus far, I can reliably repeat this in Jruby 9.4.3.0, with Java 11,17, and 20.

I am unable to replicate in JRuby 9.4.0.0 or JRuby 9.4.2.0 on any of those Javas.

Expected Behavior

Invoking concurrent ruby's Concurrent::TimerTask should work to run the code at the interval.

For example, I create a single task, then sleep in the main thread to give it a chance to run a few times before exiting gracefully.

Using jruby-9.4.0.0 and java 20.0 to works as expected:

╭─{ yaauie@maybe:~ }
╰─○ RBENV_VERSION="jruby-9.4.0.0" JENV_VERSION="20.0" JRUBY_OPTS="-Xcompile.invokedynamic=true -Xjit.threshold=0" jruby -d -rconcurrent/timer_task -e 'puts(RUBY_DESCRIPTION); Concurrent::TimerTask.execute(execution_interval: 1.0) { $stderr.puts("X") }; sleep 5'
/Users/yaauie/.rbenv/versions/jruby-9.4.0.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:14: warning: method redefined; discarding old to_int
/Users/yaauie/.rbenv/versions/jruby-9.4.0.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:14: warning: method redefined; discarding old to_f
jruby 9.4.0.0 (3.1.0) 2022-11-23 95c0ec159f OpenJDK 64-Bit Server VM 20.0.1 on 20.0.1 +indy +jit [arm64-darwin]
X
X
X
X
[success (00:00:08)]

I get the same working behavior in jruby-9.4.3.0 and java 20.0 when invokedynamic is disabled:

╭─{ yaauie@maybe:~ }
╰─○ RBENV_VERSION="jruby-9.4.3.0" JENV_VERSION="20.0" JRUBY_OPTS="-Xcompile.invokedynamic=false -Xjit.threshold=0" jruby -d -rconcurrent/timer_task -e 'puts(RUBY_DESCRIPTION); Concurrent::TimerTask.execute(execution_interval: 1.0) { $stderr.puts("X") }; sleep 5'
/Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:13: warning: method redefined; discarding old to_int
/Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:13: warning: method redefined; discarding old to_f
jruby 9.4.3.0 (3.1.4) 2023-06-07 3086960792 OpenJDK 64-Bit Server VM 20.0.1 on 20.0.1 +jit [arm64-darwin]
X
X
X
X
[success (00:00:07)]

Actual Behavior

But in JRuby 9.4.3.0 when invokedynamic is enabled, I reliably get an un-handleable exception:

java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(ThreadContext,IRubyObject,IRubyObject,IRubyObject,IRubyObject)IRubyObject to (ThreadContext,IRubyObject,IRubyObject,IRubyObject)IRubyObject

The following is the same example as above, run with jruby-9.4.3.0 and java 20.0 (but behaves the same in java 11 and 17)

╭─{ yaauie@maybe:~ }
╰─○ RBENV_VERSION="jruby-9.4.3.0" JENV_VERSION="20.0" JRUBY_OPTS="-Xcompile.invokedynamic=true -Xjit.threshold=0" jruby -d -rconcurrent/timer_task -e 'puts(RUBY_DESCRIPTION); Concurrent::TimerTask.execute(execution_interval: 1.0) { $stderr.puts("X") }; sleep 5'
/Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:13: warning: method redefined; discarding old to_int
/Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_thread_pool_executor.rb:13: warning: method redefined; discarding old to_f
jruby 9.4.3.0 (3.1.4) 2023-06-07 3086960792 OpenJDK 64-Bit Server VM 20.0.1 on 20.0.1 +indy +jit [arm64-darwin]
Unhandled Java exception: java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(ThreadContext,IRubyObject,IRubyObject,IRubyObject,IRubyObject)IRubyObject to (ThreadContext,IRubyObject,IRubyObject,IRubyObject)IRubyObject
java.lang.invoke.WrongMethodTypeException: cannot explicitly cast MethodHandle(ThreadContext,IRubyObject,IRubyObject,IRubyObject,IRubyObject)IRubyObject to (ThreadContext,IRubyObject,IRubyObject,IRubyObject)IRubyObject
             explicitCastArgumentsChecks at java/lang/invoke/MethodHandles.java:4800
                   explicitCastArguments at java/lang/invoke/MethodHandles.java:4788
                                  invoke at com/headius/invokebinder/Binder.java:1373
                        createJavaHandle at org/jruby/ir/targets/indy/Bootstrap.java:1356
                       buildNativeHandle at org/jruby/ir/targets/indy/Bootstrap.java:1061
                               getHandle at org/jruby/ir/targets/indy/InvokeSite.java:526
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:172
                      RUBY$method$post$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/java_executor_service.rb:24
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
              RUBY$method$ns_post_task$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/timer_set.rb:102
  RUBY$method$ns_post_task$0$__VARARGS__ at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/timer_set.rb:94
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                  RUBY$block$post_task$1 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/timer_set.rb:90
                             yieldDirect at org/jruby/runtime/CompiledIRBlockBody.java:151
                                   yield at org/jruby/runtime/BlockBody.java:106
                                   yield at org/jruby/runtime/Block.java:189
                         rubySynchronize at com/concurrent_ruby/ext/SynchronizationLibrary.java:217
                                    call at com/concurrent_ruby/ext/SynchronizationLibrary$JRubyLockableObject$INVOKER$i$0$0$rubySynchronize.gen:-1
                                    call at org/jruby/internal/runtime/methods/JavaMethod.java:561
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:245
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                 RUBY$method$post_task$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/timer_set.rb:90
     RUBY$method$post_task$0$__VARARGS__ at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent/executor//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/timer_set.rb:89
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                  finvokeWithRefinements at org/jruby/RubyClass.java:522
                                    send at org/jruby/RubyBasicObject.java:1703
                                    send at org/jruby/RubyKernel.java:2355
                                    call at org/jruby/RubyKernel$INVOKER$s$send.gen:-1
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
               RUBY$method$ns_schedule$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:315
   RUBY$method$ns_schedule$0$__VARARGS__ at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:312
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                    RUBY$block$execute$1 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:275
                             yieldDirect at org/jruby/runtime/CompiledIRBlockBody.java:151
                                   yield at org/jruby/runtime/BlockBody.java:106
                                   yield at org/jruby/runtime/Block.java:189
                         rubySynchronize at com/concurrent_ruby/ext/SynchronizationLibrary.java:217
                                    call at com/concurrent_ruby/ext/SynchronizationLibrary$JRubyLockableObject$INVOKER$i$0$0$rubySynchronize.gen:-1
                                    call at org/jruby/internal/runtime/methods/JavaMethod.java:561
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:245
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                   RUBY$method$execute$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:275
       RUBY$method$execute$0$__VARARGS__ at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:273
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
                   RUBY$method$execute$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/scheduled_task.rb:291
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
        RUBY$method$schedule_next_task$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/timer_task.rb:292
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                    RUBY$block$execute$1 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/timer_task.rb:210
                             yieldDirect at org/jruby/runtime/CompiledIRBlockBody.java:151
                                   yield at org/jruby/runtime/BlockBody.java:106
                                   yield at org/jruby/runtime/Block.java:189
                         rubySynchronize at com/concurrent_ruby/ext/SynchronizationLibrary.java:217
                                    call at com/concurrent_ruby/ext/SynchronizationLibrary$JRubyLockableObject$INVOKER$i$0$0$rubySynchronize.gen:-1
                                    call at org/jruby/internal/runtime/methods/JavaMethod.java:561
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:245
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:200
                   RUBY$method$execute$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/timer_task.rb:207
       RUBY$method$execute$0$__VARARGS__ at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/timer_task.rb:206
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:255
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
                   RUBY$method$execute$0 at Users/yaauie/$_dot_rbenv/versions/jruby_minus_9_dot_4_dot_3_dot_0/lib/ruby/gems/shared/gems/concurrent_minus_ruby_minus_1_dot_2_dot_2/lib/concurrent_minus_ruby/concurrent//Users/yaauie/.rbenv/versions/jruby-9.4.3.0/lib/ruby/gems/shared/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/timer_task.rb:224
                                    call at org/jruby/internal/runtime/methods/CompiledIRMethod.java:139
                                    call at org/jruby/internal/runtime/methods/MixedModeIRMethod.java:112
                     performIndirectCall at org/jruby/ir/targets/indy/InvokeSite.java:245
                                  invoke at org/jruby/ir/targets/indy/InvokeSite.java:177
                             RUBY$script at -e:1
                                     run at -e:-1
                     invokeWithArguments at java/lang/invoke/MethodHandle.java:733
                                    load at org/jruby/ir/Compiler.java:114
                               runScript at org/jruby/Ruby.java:1276
                             runNormally at org/jruby/Ruby.java:1193
                             runNormally at org/jruby/Ruby.java:1175
                             runNormally at org/jruby/Ruby.java:1211
                             runFromMain at org/jruby/Ruby.java:989
                           doRunFromMain at org/jruby/Main.java:398
                             internalRun at org/jruby/Main.java:282
                                     run at org/jruby/Main.java:227
                                    main at org/jruby/Main.java:199

[error: 1]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions