1

I'm currently checking the possibility of porting a big project from JRuby to Truffle Ruby and have hit a potential deal breaker in that the truffle documentation says Java classes cannot be reopened.

We are using the polyglot package from the GraalVM library.

Our project uses a proprietary Java map implementation (called GMap) which is used practically everywhere in our ruby code base. JRuby allows the Java class to be extended, which is very useful - not least to hide the strict Java typing.

For example, in Java we might have:

GMap map = new GMap();
map.put("k1","test");
map.put("k2", 123);
String s = map.getStr("k1"); 
int i = map.getInt("k2");
...

Whereas JRuby lets you add convenience methods to the Java class:

map = GMap.new
map[:key1] = 'test'
map[:key2] = 123
s = map[:key1]
i = map[:key2]
...

...which is much cleaner.

Does anyone know of a way of replicating this behavior in Truffle Ruby?

EDIT:

In reply to aled's comment, here is an example of a JRuby monkey patch which has been modified to use polyglot syntax:

Java.import 'org.jellyfish.gmap.GMap'

class GMap
  def [] (key)
    self.__send__(:getObj, [java.lang.String], 
      key.to_s.to_java(:string)) 
    end
  end
end 

The second line of code fails with the error:

#<Polyglot::ForeignClass[Java] type org.jellyfish.gmap.GMap> is not a class

To reproduce the error any standard java class can be used.

David Semeria
  • 542
  • 3
  • 15
  • Not sure if this is what you are looking for: [Polyglot](https://github.com/oracle/truffleruby/blob/master/doc/user/polyglot.md#loading-code-written-in-foreign-languages), also appears that TruffleRuby supports a JVM (Virtual Machine that powers JRuby) implementation by using the `--jvm` runtime configuration. – engineersmnky Jun 27 '23 at 16:54
  • Thanks @engineersmnky, I should have specified that we are running Truffle Ruby on the GraalVM. I'll update the question now. – David Semeria Jun 27 '23 at 16:57
  • Please provide a [minimal reproducible example](http://stackoverflow.com/help/minimal-reproducible-example) of how you are extending Java classes in JRuby. – aled Jun 27 '23 at 17:06
  • I don't use either so I am just trying to help as I can. I am assuming you made your way through GraalVM's Migration suggestions found here: https://www.graalvm.org/latest/reference-manual/ruby/JRubyMigration/. It seems to do a reasonable job of explaining how to implement and what Truffle can and cannot do. – engineersmnky Jun 27 '23 at 19:45

1 Answers1

1

Does GMap implement java.util.Map? If so, [] and []= are already automatically defined, as documented here.

eregon
  • 1,486
  • 14
  • 15
  • Thanks @eregon. My point is not really about [] and []=, the JRuby monkey patch file for GMap runs to about 200 lines and includes methods which only makes sense in Ruby, such as {each}. It would be very nice if I could find a way of this working under Truffle Ruby. – David Semeria Jun 27 '23 at 23:12
  • `each` is also defined, see https://github.com/oracle/truffleruby/blob/0d3058b07bf72e9a95bf48b07a32219b8d31ce77/src/main/ruby/truffleruby/core/truffle/polyglot.rb#L92-L183 `$ ruby -e 'p Java.type("java.util.HashMap").new.class.ancestors'` `[Polyglot::ForeignHash, Polyglot::HashTrait, Enumerable, Polyglot::ForeignObject, Polyglot::ObjectTrait, Object, Kernel, BasicObject]` `$ ruby -e 'p Polyglot::HashTrait.instance_methods'` `[:empty?, :tally, :zip, :find_all, :any?, :max_by, ...]` – eregon Jun 28 '23 at 09:55
  • I understand you want to define Ruby methods on a Java class, I need an example which doesn't already just work when the Java class implements the right interface (here `java.util.Map`). Could you open an issue at https://github.com/oracle/truffleruby/issues with such an example? – eregon Jun 28 '23 at 09:58
  • I misread your original comment, I didn't realize that behind the scenes polyglot maps the Ruby methods to java calls. I'll try adding the Java.util.HashMap interface to GMap and get back to you. – David Semeria Jun 28 '23 at 16:38
  • Tracked in https://github.com/oracle/truffleruby/issues/3139 – eregon Jul 04 '23 at 10:59