Embedded JRuby fails on 'require "java"'

Hello,

I’m trying to embed JRuby into extension to 3-rd party framework that
does not easily support external jars (like jruby-complete.jar). So,
after my code is loaded by the framework I manually put
jruby-complete.jar on system classpath, and try to set up JRuby
ScriptEngine manually.

public RubyEngine(File rubyJar) throws javax.script.ScriptException,

IOException {
// Set up jruby-complete.jar and System path to it
String classPath = System.getProperty(“java.class.path”);
classPath = classPath + File.pathSeparator +
rubyJar.getCanonicalPath();
System.setProperty(“java.class.path”, classPath);

    // Initialize Ruby as JSR 233 (ScriptEngine)
    ScriptEngineFactory factory = (ScriptEngineFactory) new

JRubyEngineFactory();
ScriptEngine ruby = factory.getScriptEngine();
ruby.eval(“puts $LOAD_PATH”);
ruby.eval(“require ‘irb’”);
ruby.eval(“require ‘java’”);
}

This works OK, up to a point. I can eval simple Ruby code and require
standard Ruby libraries. But it falls apart when I try to “require
‘java’”:

/builtin/java/org.jruby.ast.rb:46:in require': cannot load Java class org.jruby.ast.Node (NameError) from /builtin/javasupport.rb:46 from /builtin/javasupport.rb:1:inrequire’
from :1

I’m banging my head against this error for quite some time now.
Everything seems in order: classpath, loadpath, JRUBY_HOME… Is there
anything I’m missing here (like some setting or something) to make it
work? Any help/hints will be greatly appreciated!

Hi,

On Wed, Dec 15, 2010 at 8:10 AM, Ar Vicco [email protected] wrote:

// Set up jruby-complete.jar and System path to it
ruby.eval(“require ‘irb’”);
from /builtin/javasupport.rb:1:in `require’
from :1

Do you mean your code worked outside of the framework such as JRuby
command, but not on the framework?

-Yoko

Yoko H. wrote in post #968714:

Do you mean your code worked outside of the framework such as JRuby
command, but not on the framework?

Yes, the code works just fine on itself (with jruby-complete.jar in
classpath, of course). But when loaded by the framework, it has some
troubles with “require ‘java’” as I described. Requiring Ruby standard
libs works just fine though… weird.

Yoko H. wrote in post #968756:

If this works, I’ll fix JSR223 engine so that it will have an
appropriate classloader setting.

Yes, your code does work! I need a JSR223 engine though, not
ScriptingContainer. Is there a way to change classloader for
ScriptEngine as well? (I’m not that strong in Java, sorry…)

On Thu, Dec 16, 2010 at 12:49 AM, Ar Vicco [email protected] wrote:

Yoko H. wrote in post #968756:

If this works, I’ll fix JSR223 engine so that it will have an
appropriate classloader setting.

Yes, your code does work! I need a JSR223 engine though, not
ScriptingContainer. Is there a way to change classloader for
ScriptEngine as well? (I’m not that strong in Java, sorry…)

Thanks for confirming that code worked.

I added new option to set classloader internally. The change has been
made in jruby 1.5 branch already and included in the next 1.5 release.
However, I can’t tell you when JRuby 1.5.7 will be out. I’m hoping
1.5.7 will be released in some point.

Suppose you get JRuby 1.5.7, you can set the option before JSR223
engine is instantiated:

System.setProperty("org.jruby.embed.classloader", "current");
ScriptEngineFactory factory = (ScriptEngineFactory) new

JRubyEngineFactory();
ScriptEngine ruby = factory.getScriptEngine();

-Yoko

On Wed, Dec 15, 2010 at 5:01 PM, Ar Vicco [email protected] wrote:

Yoko H. wrote in post #968714:

Do you mean your code worked outside of the framework such as JRuby
command, but not on the framework?

Yes, the code works just fine on itself (with jruby-complete.jar in
classpath, of course). But when loaded by the framework, it has some
troubles with “require ‘java’” as I described. Requiring Ruby standard
libs works just fine though… weird.

I’m guessing framework’s custom classloader caused the problem.
Are you using JRuby 1.5.x? If so, would you change the part of the
code and see what will happen?

//ScriptEngine ruby = factory.getScriptEngine();
ScriptingContainer ruby = new ScriptingContainer();
ruby.setClassLoader(ruby.getClass().getClassLoader());
ruby.runScriptlet(“require ‘java’”);

ScriptingContainer is included in JRuby and whose fully qualified
class name is org.jruby.embed.ScriptingContainer.
If this works, I’ll fix JSR223 engine so that it will have an
appropriate classloader setting.

-Yoko

On Fri, Dec 17, 2010 at 2:55 AM, Ar Vicco [email protected] wrote:

in one place would be extremely helpful for wannabe embedders like
myself…

I updated API document. When API docs will be replaced by new one,
property names will be there (http://jruby.org/apidocs/).
I also updated “JRuby Options” page
(http://kenai.com/projects/jruby/pages/JRubyOptions). This will help a
little, but might be better than nothing. I’ll update RedBridge pages,
maybe after wiki pages are migrated.

-Yoko

Thanks a lot, Yoko!

I’ll be waiting for 1.5.7 release then.

BTW, is there a comprehensive list of all “org.jruby.embed.*” properties
(and their values) that are relevant to ScriptEngineFactory/ScriptEngine
somewhere? I cannot find such list on JRuby wiki or docs, only scattered
references to some of the properties…

Having authoritative and comprehensive list of all relevant properties
in one place would be extremely helpful for wannabe embedders like
myself…

Thanks Yoko, updated Options page is really useful for quick lookup!

I am having the same problem using jruby from cron. I have gone thru
rudimentary of doing bash -l -c “rvm jruby & ruby some_ruby.script”. The
code runs upto the point where it hits “require java”. Any ideas will be
helpful.

Thanks

Please try without rvm. If the problem goes away, it is an RVM issue.

I am sure it is a RVM issue in conjunction with cron.

The only version of JRuby I have is in RVM. I have considered installing
a system JRuby, but hesitated. I will have to do it now as I don’t see a
way forward.

Thanks for the effort.

Hirotsugu A. wrote in post #978768:

Please try without rvm. If the problem goes away, it is an RVM issue.