0

This post is related to this one : How to put properly a libgdx application inside swing application? but the question is different.

In this post I explained that I have two JARs : WorldEditor.jar and GameEngine.jar, and I load GameEngine.jar at runtime from WorldEditor.jar.

My problem is with one of the libraries included in GameEngine.jar, namely JRuby.

When I run java -jar GameEngine.jar everything is fine, but when I launche java -jar worldEditor.jar, the instance of JRuby ScriptManager I use returns null when I call ``getEngineByName`. I just can't point ou what is the problem.

By tracing the list of ScriptManagerFactories, I saw that in the good case I have [JRuby, Rhino], and in the bad one I have only [Rhino].

Would someone have an idea of what's going on ?

Community
  • 1
  • 1
dooxe
  • 1,481
  • 12
  • 17

1 Answers1

1

I don't have much experience with Java's ScriptEngine, but I ran into this issue while answering another question here. I think your problem boils down to classpath order issues.

Using this code:

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Script {
    public static void main(String args[]) throws Exception {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("jruby");
        System.out.println(engine);
    }
}

If I run it two different ways, I get two different results:

$ java -cp .:jruby.jar Script
null
$ java -cp jruby.jar:. Script
org.jruby.embed.jsr223.JRubyEngine@30c01f1c

Looking into it a bit, there is a special file in the jar that registers the various scripting containers:

The ScriptEngineManager uses the service provider mechanism described in the Jar File Specification to obtain instances of all ScriptEngineFactories available in the current ClassLoader.

My guess is that the JVM doesn't need to load the JRuby jar in the first case, so it hasn't registered the scripting engine. It would only load that jar when it cannot find some class. This means you might be able to force it to work by using some JRuby object before you ever call into the script.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • First, thanks for replying. I finally solved my problem, I forgot to answer my post because no one was replying... Actually, `ScriptManager` constructor can take a `ClassLoader` as parameter. So you just have to create a script manager with `new ScriptManager(MyClassInMySuperJar.class.getClassLoader())`, and then it works. – dooxe Jan 24 '14 at 15:26