在 Java 11 下运行的旧版 JRuby 应用程序 (1.6.8) 上工作时,我在测试用例中发现了一个特殊错误:"require 'java'; puts java::util::regex::Pattern.class"
errors ArgumentError: wrong number of arguments (0 for 1)
。对于其他内置 JRE 类,这似乎工作正常(见下文)。
这会导致 JRuby 本身有时会失败,在https://github.com/jruby/jruby/blob/1.6.8/lib/ruby/site_ruby/shared/builtin/javasupport/core_ext/object.rb#L10中的这一行:
if self.class.superclass.instance_method(:method_added) != method(:java_package_method_added)
为了让应用程序正常工作,我必须在 JRuby 源代码中注释掉该行。
我对造成这种情况的原因或如何适当地解决它感到困惑。谷歌展示了几个人们在尝试加载特定应用程序时遇到该错误的实例,但没有人弄清楚原因(所有解决方案都说“尝试不同版本的应用程序)。
为什么 JRuby 不能执行.class
?它期待什么论据?
完整的跟踪如下:
$ java -version
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
$ ./jruby -v
jruby 1.6.8 (ruby-1.8.7-p357) (2012-09-18 1772b40) (Java HotSpot(TM) 64-Bit Server VM 11.0.1) [linux-amd64-java]
$ ./jruby -e "require 'java'; puts java::util::regex::Matcher.class"
WARNING: An illegal reflective access operation has occurred
...
Class
$ ./jruby -e "require 'java'; puts java::lang::String.class"
WARNING: An illegal reflective access operation has occurred
...
Class
$ ./jruby -e "require 'java'; puts java::util::regex::Pattern.class"
WARNING: An illegal reflective access operation has occurred
....
ArgumentError: wrong number of arguments (0 for 1)
(root) at -e:1
Java 行为
Java本身似乎没有问题:
jshell> int.class
$6 ==> int
jshell> String.class
$7 ==> class java.lang.String
jshell> Pattern.class
$8 ==> class java.util.regex.Pattern
jshell> Pattern.class.getClass()
$12 ==> class java.lang.Class
jshell> String.class.getClass()
$13 ==> class java.lang.Class
部分解决方案?
我可以通过注释掉if
上面引用的语句来修复 JRuby 中的这个错误。但是,在这个遗留应用程序中,JRuby 位于已编译的 jar 中,因此我无法编辑其源代码。有没有办法在不更改二进制 jar 的情况下向 JRuby 添加猴子补丁来修复失败的if
语句?
获取 JRuby
JRuby 1.6.8 可在http://central.maven.org/maven2/org/jruby/jruby-dist/1.6.8/ 获得