Java_send with a CharSequence not working

Consider the following in irb:


a = java.lang.StringBuilder.new
a.java_send :append, [java.lang.String], “I am Here\n”
puts a


yields “I am Here”, as expected.


a.java_send :append, [java.lang.CharSequence], “I am not here!\n”
a.java_send :append, [java.lang.CharSequence], “I am not
here!\n”.to_java


both yield

TypeError: cannot convert instance of class org.jruby.RubyModule to
class java.lang.Class
from org/jruby/java/proxies/JavaProxy.java:347:in java_send' from (irb):76:inevaluate’
from org/jruby/RubyKernel.java:1107:in eval' from org/jruby/RubyKernel.java:1507:inloop’
from org/jruby/RubyKernel.java:1270:in catch' from org/jruby/RubyKernel.java:1270:incatch’
from C:/jruby-1.7.18/bin/jirb:13:in `(root)’

Lets get extreme and open Ruby’s String as follows:


class String
include java.lang.CharSequence

def charAt(index)
self.to_java.charAt(index)
end

def length
self.to_java.length
end

def subSequence(start, endPoint)
self.to_java.subSequence(start, endPoint)
end

def toString
self.to_java.toString()
end

end


The code “SomeString”.toString behaves as expected now, but:


a.java_send :append, [java.lang.CharSequence], “Some String”


TypeError: cannot convert instance of class org.jruby.RubyModule to
class java.lang.Class
from org/jruby/java/proxies/JavaProxy.java:347:in java_send' from (irb):81:inevaluate’
from org/jruby/RubyKernel.java:1107:in eval' from org/jruby/RubyKernel.java:1507:inloop’
from org/jruby/RubyKernel.java:1270:in catch' from org/jruby/RubyKernel.java:1270:incatch’
from C:/jruby-1.7.18/bin/jirb:13:in `(root)’

Still fails :frowning:

I read this line
a.java_send :append, [java.lang.String], “I am Here\n”
as equivalent to
a.append(java.lang.String.new(“I am Here\n”))

Why use java_send in the first place?

So using [java.lang.String] means more or less a creation of a new java
String or casting from ruby String into java String.

But java.lang.CharSequence is an interface… not a java type. I doubt
you
can cast into it… Verification below

java.lang.CharSequence.new(‘boo’)
from org/jruby/java/proxies/JavaInterfaceTemplate.java:393:in
new' from (irb):16:inevaluate’
from org/jruby/RubyKernel.java:1112:in eval' from C:/dev/rb/lib/ruby/1.8/irb.rb:158:ineval_input’
from C:/dev/rb/lib/ruby/1.8/irb.rb:271:in signal_status' from C:/dev/rb/lib/ruby/1.8/irb.rb:155:ineval_input’
from org/jruby/RubyKernel.java:1439:in loop' from org/jruby/RubyKernel.java:1212:incatch’
from C:/dev/rb/lib/ruby/1.8/irb.rb:154:in eval_input' from C:/dev/rb/lib/ruby/1.8/irb.rb:71:instart’
from org/jruby/RubyKernel.java:1212:in catch' from C:/dev/rb/lib/ruby/1.8/irb.rb:70:instart’
from C:\dev\rb\bin\jirb:13:in `(root)’

Could you please show in plain java what you’re trying to achieve with
CharSequence?

I opened this as a bug here:

They already submitted a patch in an upcoming release (4 hours after
submission – fast!!).

To answer your question… Why use java_send in the first place?

To force JRuby to use the overloaded method of my choosing. I
understand that I do not have to, but if I had called a preexisting
library that returned a CharSequence I wanted to be able to avoid the
intermediate object creation.

Cris