atom feed4 messages in net.java.dev.scripting.usersRe: JRuby ScriptEngine problem when u...
FromSent OnAttachments
Suhas GadekarJun 27, 2008 8:11 am 
Jim WhiteJun 27, 2008 9:09 am 
Suhas GadekarJun 27, 2008 10:15 am 
Suhas GadekarJun 28, 2008 10:21 pm 
Subject:Re: JRuby ScriptEngine problem when used inside the OSGi container
From:Suhas Gadekar (Suha@Sun.COM)
Date:Jun 28, 2008 10:21:44 pm
List:net.java.dev.scripting.users

If you look at JRubyScriptEngine you'll see that there is a classpath

property "com.sun.script.jruby.loadpath" which in the init method defaults to "java.class.path" if null.

That's true, and that behavior was causing the problem using the ScriptEngine from inside an OSGi bundle.

In OSGi container, every bundle gets a separate classloader with its own classpath, and if JRubyScriptEngine hypothetically would have used bundle's classpath instead of the "java.class.path", it would have worked.

As a workaround, I explicitly set Bundle's class-path as the "com.sun.script.jruby.loadpath" system property, thereby preventing JRubyScriptEngine from using the default "java.class.path" and it worked. Here is the code snippet:

//ctx - BundleContext object of OSGi String bundleClasspath = (String)ctx.getBundle().getHeaders().get("Bundle-ClassPath"); System.setProperty("com.sun.script.jruby.loadpath", bundleClasspath); // Now get the engine..

Suhas

Thanks Jim for a quick reply. I am using JDK 1.6 on Solaris as well as OS X, and the problem occurs on both the platforms.

I think the following provider-discovery and instantiation mechanism equivalent of the RI seems to be working(may not be completely), because I can get the factory and can print information such as LanguageName, Extensions supported etc.

Enumeration factoryResources = classLoader.getResources("META-INF/services/javax.script.ScriptEngineFactory");

In addition, I tried printing the class name of the factory after getting it from the ScriptEngineManager and it correctly showed: "com.sun.script.jruby.JRubyScriptEngineFactory"

As far as class-loader, it does use OSGi's class loader to load the factory; and as you pointed out I will look into this more: "org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader@151d4a91"

It is good to know of the extender PAX script. And yes, the JRuby engine worked absolutely fine outside of the OSGi container for me, just not in the container. It is clear the class-loader used is different, but could that be the problem because it did find the JRubyScriptEngineFactory class?

I tried directly using the com.sun.script.jruby.JRubyScriptEngineManager, but same exception; so I guess I will look into "com.sun.script.jruby.loadpath".

If you look at JRubyScriptEngine you'll see that there is a classpath property "com.sun.script.jruby.loadpath" which in the init method defaults to "java.class.path" if null.

I don't know what the OSGi code is doing but I suspect that one way or another the classpath isn't specified the way JRuby wants it. But I'm not sure since the exception is probably from the runtime.getLoadService().require("java") call.

As for the null results from the manager, that indicates that JRubyScriptEngineFactory is not getting registered with ScriptEngineManager. Once again this is a classpath problem.

You don't indicate whether you're using JDK 1.5 or 1.6. I've not looked at the code for ScriptEngineManager in JDK 1.6, but when using 1.5 the way the available factories are found is this (this is from the LiveTribe JSR-223 implementation, but the RI is similar):

public ScriptEngineManager() { this(Thread.currentThread().getContextClassLoader()); }

@SuppressWarnings({ "EmptyCatchBlock" }) public ScriptEngineManager(ClassLoader classLoader) { try { Enumeration factoryResources = classLoader.getResources("META-INF/services/javax.script.ScriptEngineFactory");

So if the OSGi container isn't managing the classpath in an equivalent way, then again your problem is in that area.

If you're not subscribed to the list, then you may have missed a couple posts that could be helpful:

From Hendy Irawan:

Pax-Script is an extender that automatically registers JSR223 engines (javax.script.ScriptEngineFactory) as OSGi services when a JSR223 JAR is loaded.

SCM: http://scm.ops4j.org/browse/OPS4J/laboratory/users/ceefour/pax-script

Also "jointly developed" with JSR223: https://scripting.dev.java.net/issues/show_bug.cgi?id=34

An effort is undergoing to make all JSR223 engines OSGi-compliant. Right now Groovy engine is directly usable by Pax-Script. ... http://wiki.ops4j.org/confluence/display/ops4j/Laboratory

I can report though that the JRuby engine does work fine though when the classpath is correct, as well as quite a few others (I recently got OCaml-Java working), which you can see for yourself in IFCX Wings. IFCX.org also hosts JDK 1.5 versions of the scripting.dev.java.net engines, along with some patches for improved functionality which I will be posting here when time permits.

http://www.ifcx.org/

Suhas Gadekar wrote:

Hi All,

I am not on the alias, so please reply to me directly. I am using JRuby Scripting Engine inside an OSGi container and the ScriptEngineManager returns null when asked for the JRuby engine. I see however that the JRuby ScriptEngineFactory is returned successfully and can see/print information about the factory.

Here is some code snippet:

// manager - ScriptManager, factory - JRuby ScriptEngineFactory retrieved from the manager // engine - ScriptEngine

System.out.println("Engine Name: "+factory.getEngineName()); // Prints: Engine Name: JRuby Engine System.out.println("Language Name: "+factory.getLanguageName()); // Prints: Language Name: ruby System.out.println("Extension Names: "+factory.getExtensions()); // Prints: Extension Names: [rb]

// Good so far

engine = manager.getEngineByName(factory.getLanguageName()); System.out.println("Engine by name:"+engine); // Prints: Engine by name: null

engine = manager.getEngineByName(factory.getExtensions().get(0)); System.out.println("Engine by extension:"+engine); //Prints: Engine by exrension: null

engine = factory.getScriptEngine(); System.out.println("Engine:"+engine); // Hangs and after 5-10min, an exception(stacktrace given below) in OSGi console.

Any ideas?

Exception: factory.getScriptEngine()... Caused by: org.jruby.exceptions.RaiseException: library `java' could not be loaded: org.jruby.exceptions.RaiseException: no such file to load -- builtin/javasupport Nested Exception: :1: library `java' could not be loaded: org.jruby.exceptions.RaiseException: no such file to load -- builtin/javasupport (LoadError) ...internal jruby stack elided... Nested Exception: :1: library `java' could not be loaded: org.jruby.exceptions.RaiseException: no such file to load -- builtin/javasupport (LoadError) ...internal jruby stack elided...