Skip to content

RubyObjectInvocationHandler invoke method throw ClassCastException when return value is java primitive wrapper object [SPR-3038] #7724

@spring-projects-issues

Description

@spring-projects-issues

chris tam opened SPR-3038 and commented

RubyObjectInvocationHandler will throw ClassCastException when calling a java method which return a java primitive wrapper object, like java.lang.Integer, java.lang.Long and so on. For example:
In the java interface class, the following method is defined:
...
public Integer getAge() ;
...
In the JRuby file, the corresponding method is
...
def getAge
return @age
end
...
When the "getAge" method is called, it will throw the ClassCastException because the JavaUtil.convertRubyToJava(result, method.getReturnType()) always try to cast the result object to JRuby JavaObject. I don't know JRuby has fixed this problem or not but I would suggest to work around this problem in the current RubyObjectInvocationHandler using the following code:
...
Class returnClazz = method.getReturnType() ;
Object obj = convertRubyToJavaPrimitiveWrapper(result, returnClazz) ;
if (obj == null) {
obj = JavaUtil.convertRubyToJava(result, returnClazz);
}
return obj ;
...
private Object convertRubyToJavaPrimitiveWrapper(IRubyObject rubyObject, Class javaClass) {
if (rubyObject == null || rubyObject.isNil()) {
return null;
}

ThreadContext context = rubyObject.getRuntime().getCurrentContext();

String cName = javaClass.getName();
if (cName == "java.lang.Boolean") {
return Boolean.valueOf(rubyObject.isTrue());
} else if (cName == "java.lang.Float") {
if (rubyObject.respondsTo("to_f")) {
return new Float(((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue());
}
return new Float(0.0);
} else if (cName == "java.lang.Double") {
if (rubyObject.respondsTo("to_f")) {
return new Double(((RubyNumeric) rubyObject.callMethod(context, "to_f")).getDoubleValue());
}
return new Double(0.0);
} else if (cName == "java.lang.Long") {
if (rubyObject.respondsTo("to_i")) {
return new Long(((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
}
return new Long(0);
} else if (cName == "java.lang.Integer") {
if (rubyObject.respondsTo("to_i")) {
return new Integer((int) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
}
return new Integer(0);
} else if (cName == "java.lang.Short") {
if (rubyObject.respondsTo("to_i")) {
return new Short((short) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
}
return new Short((short) 0);
} else if (cName == "java.lang.Byte") {
if (rubyObject.respondsTo("to_i")) {
return new Byte((byte) ((RubyNumeric) rubyObject.callMethod(context, "to_i")).getLongValue());
}
return new Byte((byte) 0);
}

// not primitive wrapper object, just return null ;
return null ;

}


Affects: 2.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: coreIssues in core modules (aop, beans, core, context, expression)type: bugA general bug

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions