Extending (monkey patching) Java classes in Truffle Ruby

134 views Asked by At

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.

1

There are 1 answers

5
eregon On

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