jruby / jruby

JRuby, an implementation of Ruby on the JVM
https://www.jruby.org
Other
3.79k stars 922 forks source link

[ji] should allow calling protected Java method with send #5310

Open kares opened 6 years ago

kares commented 6 years ago

... works on Java 8 but not on 10(+)

jruby 9.2.1.0-SNAPSHOT (2.5.0) 2018-09-11 055a178 Java HotSpot(TM) 64-Bit Server VM 10.0.1+10 on 10.0.1+10 +jit [linux-x86_64]
irb(main):001:0> Java::JavaUtilLogging::StreamHandler.new.setOutputStream
Traceback (most recent call last):
        6: from /home/kares/workspace/oss/jruby/bin/jirb:13:in `<main>'
        5: from org/jruby/RubyKernel.java:1178:in `catch'
        4: from org/jruby/RubyKernel.java:1178:in `catch'
        3: from org/jruby/RubyKernel.java:1412:in `loop'
        2: from org/jruby/RubyKernel.java:1040:in `eval'
        1: from (irb):1:in `evaluate'
NoMethodError (undefined method `setOutputStream' for #<Java::JavaUtilLogging::StreamHandler:0x18a645fd>)
irb(main):002:0> Java::JavaUtilLogging::StreamHandler.new.send :setOutputStream, nil
Traceback (most recent call last):
        6: from /home/kares/workspace/oss/jruby/bin/jirb:13:in `<main>'
        5: from org/jruby/RubyKernel.java:1178:in `catch'
        4: from org/jruby/RubyKernel.java:1178:in `catch'
        3: from org/jruby/RubyKernel.java:1412:in `loop'
        2: from org/jruby/RubyKernel.java:1040:in `eval'
        1: from (irb):2:in `evaluate'
NoMethodError (undefined method `setOutputStream' for #<Java::JavaUtilLogging::StreamHandler:0x4650a407>)

the first failure is fine (although if it would be marked as a protected instance method the failure would be different), setOutputStream is a protected Java method, the second would be more Ruby if it worked ... this all works on Java 8 - would argue the direct call working is not something JRuby encouraged or specified, nevertheless the second from should work everywhere - seems like we can not set it accessible (due JDK modularization?).

extracted from: https://github.com/jruby/jruby/issues/4851#issuecomment-420378298

related - similar accessibility issue on Java 10: https://github.com/jruby/jruby/issues/5284

prashantvithani commented 6 years ago

@kares Is there any workaround to solve this other than downgrading to Java-8?

ckpeter commented 5 years ago

Can confirm that this is happening on Java 11. Trinidad is throwing exception on startup due to this.

I could not find any workaround except downgrading to Java 8, or on Java 11, manually going into Trinidad logging code and disabling the call.

Here is another test case:


puts "JRuby: #{JRUBY_VERSION}"
puts "Java: #{java.lang.System.getProperty('java.runtime.version')}"
obj = java.util.logging::ConsoleHandler.new
puts "java.util.logging::ConsoleHandler.set_output_stream: #{obj.methods.include?(:set_output_stream)}"

C:\dir>ver

Microsoft Windows [Version 10.0.17134.523]

C:\dir>set JAVA_HOME=\bin\jdk8

C:\dir>jruby test.rb JRuby: 9.2.5.0 Java: 1.8.0_92-b14 java.util.logging::ConsoleHandler.set_output_stream: true

C:\dir>set JAVA_HOME=\bin\jdk11

C:\dir>jruby test.rb JRuby: 9.2.5.0 Java: 11.0.2+9-LTS java.util.logging::ConsoleHandler.set_output_stream: false

headius commented 2 years ago

I stumbled on this looking for bugs about calling protected methods but I believe opening the target package to JRuby should work. The syntax for a target class a.b.Cookie should be something like:

.jruby.java_opts

--add-opens <module>/a.b=org.jruby.dist

Where <module> could be:

It will depend on the target library and how it is being loaded.

The org.jruby.dist might be org.jruby.base or org.jruby.complete if you are launching JRuby as a Java application rather than via our bin/jruby launcher.