How to create a Ruby module in Java using JRuby?
java, jruby, module, ruby
Solution
Here's how would implement exactly the same code you have above using a Java extension.
Everything here is at the default package level (no package), if you would like to have packages just change the module name.
First, create the Greeter class:
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
public class Greeter {
@JRubyMethod
public static void greet( ThreadContext context, IRubyObject self ) {
System.out.printf("Hello from %s%n", self);
}
}
Then you need the GreeterService to load it:
import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.runtime.load.BasicLibraryService;
import java.io.IOException;
public class GreeterService implements BasicLibraryService {
@Override
public boolean basicLoad(final Ruby runtime) throws IOException {
RubyModule greeter = runtime.defineModule(Greeter.class.getSimpleName());
greeter.defineAnnotatedMethods(Greeter.class);
return true;
}
}
And with these classes defined, here's how you can use them in a JRuby script:
require 'target/jruby-example.jar'
require 'greeter'
class MyClass
include Greeter
end
obj = MyClass.new
obj.greet
The `jruby-example.jar` contains both classes above compiled and packaged. There isn't much else to be done here, now you have your module that you can include anywhere. For a bigger example, just check how the Enumerable module is implemented.
Problem
In Ruby, I can have a module like: ``` module Greeter def greet print "Hello" end end ``` And my class can get the `greet` method like this: ``` class MyClass include Greeter end obj = MyClass.new obj.greet ``` Now, I would like to have my module `Greeter` implemented in Java instead. I'm using JRuby. I'm unsure about how to create a Ruby module in Java (in such a way that I can do `include` normally). For a moment I though of making a Java interface. Including it in my Ruby class doesn't throw errors, but it really isn't the same thing since modules seem to implement the methods, whereas a Java interface doesn't.