How to return Jruby proc / block / close in java and call it

I need the ability to return blocks from a built-in jruby instance to regular java. My java code should be able to pass the required parameters (suggesting that it knows the correct arity), and then gets the result. Any samples will be appreciated.

+4
source share
1 answer

If you can make a direct attachment, use JavaEmbedUtils and call eval on the line of ruby ​​code that defines your proc / block / clos or your ruby ​​code that implements an interface where certain methods return your proc / block / close. An incredibly contrived example to summarize the two numbers below:

SampleApp.java

import org.jruby.Ruby; import org.jruby.RubyRuntimeAdapter; import org.jruby.RubyFixnum; import org.jruby.RubyProc; import org.jruby.javasupport.JavaEmbedUtils; import org.jruby.runtime.Block; import org.jruby.runtime.ThreadContext; import java.util.ArrayList; class SampleApp { public static void main(String[] args) { // Create runtime instance Ruby runtime = JavaEmbedUtils.initialize(new ArrayList()); // Parameters RubyFixnum paramA = new RubyFixnum(runtime, 1); RubyFixnum paramB = new RubyFixnum(runtime, 2); // Runtime eval method RubyRuntimeAdapter evaler = JavaEmbedUtils.newRuntimeAdapter(); RubyProc additionProcFromEval = (RubyProc)evaler.eval(runtime, "Proc.new { |a, b| a + b }"); printProcResult(runtime, additionProcFromEval, paramA, paramB); // Interface implementation method SomeInterfaceImpl someImpl = new SomeInterfaceImpl(); RubyProc additionProcFromInterface = (RubyProc)someImpl.getAdditionProc(); printProcResult(runtime, additionProcFromInterface, paramA, paramB); // Shutdown and terminate instance JavaEmbedUtils.terminate(runtime); } protected static void printProcResult(Ruby runtime, RubyProc proc, RubyFixnum paramA, RubyFixnum paramB) { Block block = proc.getBlock(); ThreadContext threadContext = ThreadContext.newContext(runtime); int result = (Integer)block.call(threadContext, paramA, paramB).toJava(new Integer(0).getClass()); System.out.println("Result = " + result); } } 

SomeInterface.java

 interface SomeInterface { org.jruby.RubyProc getAdditionProc(); } 

SomeInterfaceImpl.rb

 require 'java' class SomeInterfaceImpl include Java::SomeInterface java_signature 'org.jruby.RubyProc getAdditionProc()' def getAdditionProc() return Proc.new { |a, b| a + b } end end 

And here is how you can test:

 javac -classpath jruby.jar SomeInterface.java jrubyc --javac -cp . SomeInterfaceImpl.rb javac -cp jruby.jar:. SampleApp.java java -cp jruby.jar:. SampleApp 

Literature:

https://github.com/jruby/jruby/wiki/DirectJRubyEmbedding

http://tommy.chheng.com/2010/06/20/call-a-jruby-method-from-java/

+1
source

All Articles