[英]Java Reflection: Determining class of java.util.regex.Pattern in JRuby
Working on a legacy JRuby app (1.6.8) running under Java 11, I traced a peculiar error a test case: "require 'java'; puts java::util::regex::Pattern.class"
errors ArgumentError: wrong number of arguments (0 for 1)
. 在运行于Java 11下的旧版JRuby应用程序(1.6.8)上工作时,我跟踪了一个测试案例的异常错误:
"require 'java'; puts java::util::regex::Pattern.class"
错误ArgumentError: wrong number of arguments (0 for 1)
。 For other built-in JRE classes, this seems to work fine (see below). 对于其他内置JRE类,这似乎可以正常工作(请参见下文)。
This causes JRuby itself to fail sometimes, at this line in https://github.com/jruby/jruby/blob/1.6.8/lib/ruby/site_ruby/shared/builtin/javasupport/core_ext/object.rb#L10 : 这有时会导致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)
To get the app to work, I had to comment out that line in the JRuby source. 为了使该应用程序正常工作,我不得不在JRuby源代码中注释掉该行。
I'm perplexed as to the cause of this, or how to fix it appropriately. 我对此感到困惑,或如何适当地解决它。 Google shows several instances of people getting that error when trying to load particular apps, but no one figuring out why (all the solutions said "try different versions of the app).
Google展示了许多人在尝试加载特定应用程序时遇到该错误的实例,但没有人弄清楚原因(所有解决方案都说“尝试不同版本的应用程序”)。
Why can JRuby not execute .class
? 为什么JRuby无法执行
.class
? What argument is it expecting ? 期待什么论点 ?
Complete trace below: 完整的跟踪如下:
$ 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 itself seems to have no problem: 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
I can fix this error in JRuby by commenting out the if
statement referenced above. 我可以通过注释掉上面引用的
if
语句来解决JRuby中的错误。 However, on this legacy app, JRuby is in a compiled jar, and so I can't edit its source. 但是,在此旧版应用程序上,JRuby位于编译的jar中,因此我无法编辑其源代码。 Is there a way to add a monkey patch to JRuby, without changing the binary jar, to fix the failing
if
statement? 有没有一种方法可以在不更改二进制jar的情况下向JRuby添加猴子补丁来修复失败的
if
语句?
JRuby 1.6.8 is available at http://central.maven.org/maven2/org/jruby/jruby-dist/1.6.8/ 可从http://central.maven.org/maven2/org/jruby/jruby-dist/1.6.8/获得JRuby 1.6.8。
I think that jruby is trying to read one of members of Pattern class: 我认为 jruby正在尝试读取Pattern类的成员之一:
private static int getClass(int c) {
return sun.text.Normalizer.getCombiningClass(c);
}
as it looks a bit like getter but have that extra argument. 因为它看起来有点像吸气剂,但要有额外的论点。
You can confirm that by creating own class like that: 您可以通过创建自己的类来确认这一点:
class MyClass {
private static int getClass(int c) {
return 4;
}
}
And then try to get class from it in JRuby. 然后尝试在JRuby中从中获取类。
It works with java 8 as this method was non-static, and like Holger said jruby seems to prefer to use existing static methods even if they do not match signature, and check for special ".class" property is done at the end. 它可以与Java 8一起使用,因为该方法是非静态的,并且像Holger所说,jruby似乎更喜欢使用现有的静态方法,即使它们与签名不匹配,并在最后检查特殊的“ .class”属性。 (As in java
Something.class
is not a property, but just a keyword) (就像在Java中,
Something.class
不是属性,而只是关键字)
Best option would be to have higher priority for methods that are matching invocation (0 needed arguments), and maybe for public methods. 最好的选择是对与调用匹配的方法(需要的0个参数)以及公共方法具有更高的优先级。 Also getters should probably only be matched by name of property only if they are really getters - so they do not have any arguments.
同样,仅当吸气剂确实是吸气剂时,才可能仅应按属性名称进行匹配-因此它们没有任何参数。
Download for this version of jruby does not work for me, so I can't test this: https://www.jruby.org/files/downloads/1.6.8/index.html 此版本的jruby的下载不适用于我,因此无法对此进行测试: https : //www.jruby.org/files/downloads/1.6.8/index.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.