I am building a Spark application that make use of some feature already developed in Ruby.
I made the choice to invoke the Ruby part from my Scala main by defining MyProxy
class in ruby and compiling with JRuby.
I can then use MyProxy
to invoke the rest of the Ruby code that stay in scripts. Foremost reason is that I was unable to compile them with JRuby, probably because they are too dynamic:
## myProxy.rb -> compiled into myProxy.class
## jrubyc --javac myProxy.rb
require 'java'
java_package 'ruby.proxy'
require_relative 'some.rb'
class MyProxy
def self.invoke_script()
... ## invoke some other ruby in script that are note compiled by jrubyc
end
end
and the Scala Main:
object myRun extends App {
val something = MyProxy.invoke_script()
...
}
At runtime the flow looke like this:
Main.class (scala) -> call myProxy.class (compiled ruby of myProxy.rb) -> call function in script.rb
It works, and I was able to make a runnable jar for the Scala and compiled ruby part. But when I am running it: java -jar myApp.jar
,
it still need to access my myProxy.rb file and, of course, all other scrips.rb.
So I need a copy of all my ruby scripts in the working directory when executing this command.
Ideally I would like to include all the ruby scripts in the myApp.jar as well, and be able to deploy easily deploy on a spark cluster. Is this possible, and how?
I have looked at warbler and rawr. However, I don't see how these tools can help me in this mixed environment (main in Java, some part compiled ruby, some part pure scripts).
Any help appreciated!
As stated in the jruby documentation, packaging ruby scripts in a jar, should be has simple as including them in the .jar (sic):
Everything in the Java classpath is considered to be a load path entry, so .rb scripts, for example, contained in JAR files, are loadable.
It wasn't working in my case, because I was using require_relative in my script, which doesn't seem to work properly in recent release of JRuby. Replacing require_relative with require made it works with scripts embedded in myApp.jar.
Moreover using require_relative 'toto'
in titi.rb was triggering an error of titi.rb script not found, which was misleading since it was titi.rb which was being executed.