简体   繁体   English

Java反射:在JRuby中确定java.util.regex.Pattern的类

[英]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 behavior Java行为

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

Partial Solution? 部分解决方案?

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语句?

Getting JRuby 获取JRuby

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.

相关问题 java.util.regex.Pattern的正则表达式 - Regular expression for java.util.regex.Pattern 使用java.util.regex.Pattern在java中查找类似的IP - find similar IP in java using java.util.regex.Pattern Liferay中java.util.regex.Pattern处的java.lang.StackOverflowError - java.lang.StackOverflowError at at java.util.regex.Pattern in liferay 添加到java.util.regex.Pattern或合并它们 - Adding onto a java.util.regex.Pattern or Merging Them (java.util.regex.Pattern的问题)检查字符串的数字和字母 - (Problems with java.util.regex.Pattern) checking string for digits and letters 从java.util.regex.Pattern中的字符类减去反向引用中的字符 - Subtracting characters in a back reference from a character class in java.util.regex.Pattern java.util.regex.Pattern 可以进行部分匹配吗? - Can java.util.regex.Pattern do partial matches? 如何使用 protobuf 序列化 java.util.regex.Pattern? - How to serialize a java.util.regex.Pattern using protobuf? java.util.regex.PatternSyntaxException:null(在java.util.regex.Pattern中)错误 - java.util.regex.PatternSyntaxException: null (in java.util.regex.Pattern) error java.util.regex.Pattern和java.util.regex.Matcher的设计有什么好处? - What is benefit in design of java.util.regex.Pattern and java.util.regex.Matcher?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM