Details
Description
I had no problems using BSF from JRuby 1.1.2 or earlier.
Since JRuby 1.1.3 when trying to use BSF I get the following error:
$ jruby --debug testJava.rb
Hello from Ruby
unable to load language: ruby: java.lang.NoClassDefFoundError: org/apache/bsf/util/BSFEngineImpl
at java.lang.ClassLoader.findBootstrapClass(Native Method)
at java.lang.ClassLoader.findBootstrapClass0(ClassLoader.java:891)
at java.lang.ClassLoader.loadClass(ClassLoader.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at org.apache.bsf.BSFManager.loadScriptingEngine(Unknown Source)
at org.apache.bsf.BSFManager.eval(Unknown Source)
at TestBSF.<init>(TestBSF.java:12)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.jruby.javasupport.JavaConstructor.new_instance(JavaConstructor.java:195)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jruby.internal.runtime.methods.ReflectedJavaMethod.call(ReflectedJavaMethod.java:143)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:134)
at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:279)
at org.jruby.ast.CallNode.interpret(CallNode.java:163)
at org.jruby.ast.AttrAssignOneArgNode.interpret(AttrAssignOneArgNode.java:32)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:67)
at org.jruby.internal.runtime.methods.DefaultMethod.interpretedCall(DefaultMethod.java:171)
at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:147)
at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:203)
at org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:111)
at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:282)
at org.jruby.ast.FCallNode.interpret(FCallNode.java:139)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.internal.runtime.methods.DefaultMethod.interpretedCall(DefaultMethod.java:171)
at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:147)
at org.jruby.RubyClass.invoke(RubyClass.java:243)
at org.jruby.javasupport.util.RuntimeHelpers.invoke(RuntimeHelpers.java:270)
at org.jruby.RubyObject.callMethod(RubyObject.java:711)
at org.jruby.RubyClass.newInstance(RubyClass.java:275)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jruby.internal.runtime.methods.ReflectedJavaMethod.call(ReflectedJavaMethod.java:143)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:134)
at org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:76)
at org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:111)
at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:282)
at org.jruby.ast.FCallNode.interpret(FCallNode.java:139)
at org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:115)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:67)
at org.jruby.internal.runtime.methods.DefaultMethod.interpretedCall(DefaultMethod.java:171)
at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:147)
at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:224)
at org.jruby.runtime.CallSite$InlineCachingCallSite.cacheAndCall(CallSite.java:123)
at org.jruby.runtime.CallSite$InlineCachingCallSite.call(CallSite.java:333)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:61)
at org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:115)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:67)
at org.jruby.ast.RootNode.interpret(RootNode.java:126)
at org.jruby.Ruby.runInterpreter(Ruby.java:561)
at org.jruby.Ruby.runNormally(Ruby.java:460)
at org.jruby.Ruby.runFromMain(Ruby.java:327)
at org.jruby.Main.run(Main.java:194)
at org.jruby.Main.run(Main.java:91)
at org.jruby.Main.main(Main.java:82)
My code:
------------------------------------------
$ cat testJava.rb
require 'java'
include_class 'TestBSF'
puts "Hello from Ruby"
bsf = TestBSF.new
------------------------------------------
$ cat TestBSF.java
import org.apache.bsf.BSFException;
import org.apache.bsf.BSFManager;
public class TestBSF {
public TestBSF() {
BSFManager bsfManager = new BSFManager();
String expression = "puts \"Hello from BSF\" ";
try {
bsfManager.eval("ruby", "TestBSF", -1, -1, expression);
}
catch (BSFException e) {
e.printStackTrace();
}
}
}
The problem was that we started loading jruby.jar in the boot classpath while BSF still loaded in the main classpath. This lead to our JRubyEngine not being able to link BSFEngineImpl, since it was loaded at a deeper classloader.
The simple fix was to modify startup scripts to also include bsf.jar in the bootclasspath. Committed in r9123.