Hi all.
The upgrade to JRuby 1.6.0 broke one of our internal unit tests, and I
was wondering whether the new behaviour is intentional.
@Test
public void testErrorBehaviourForUnknownSymbol() throws Exception
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByExtension("rb");
try
{
engine.eval("# extra lines to confirm that \n" +
"# the line number is accurate \n" +
"no_method_with_this_name");
fail("Expected ScriptException");
}
catch (ScriptException e)
{
RaiseException cause = (RaiseException) e.getCause();
// Neither printStackTrace nor toString should throw
exceptions.
cause.toString();
StringWriter writer = new StringWriter();
//noinspection IOResourceOpenedButNotSafelyClosed
cause.printStackTrace(new PrintWriter(writer));
// Checking that the string starts like this, which is the
hack I applied.
// MRI starts with this:
// -:1: undefined local variable or method
assertTrue(“Not seeing the expected error message”,
writer.toString().contains(":3: undefined local
variable or method"));
}
}
This is now failing on the eval() call with an EvalFailedException,
which doesn’t extend ScriptException.
Javadoc on eval() says that it throws ScriptException if an error
occurs in the script, so this may be incorrect behaviour, but perhaps
I’m mistaken.
TX
Adding…
I tried running the specific test by itself, and it passes. So it
seems that it’s somehow dependent on other tests run in the same
suite, which is really scary.
I found a second test exhibiting a very similar problem.
@Test
public void testErrorBehaviourForErrorFromJavaSide() throws
Exception
{
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByExtension(“rb”);
StringWriter writer = new StringWriter();
engine.getContext().setWriter(writer);
engine.getContext().setErrorWriter(writer);
try
{
engine.put("runnable", new Runnable()
{
@Override
public void run()
{
throw new RuntimeException("Got an error");
}
});
engine.eval("$runnable.run()");
fail("Expected ScriptException");
}
catch (ScriptException e)
{
RaiseException cause = (RaiseException) e.getCause();
// Now we expect the real exception in here.
RuntimeException realCause = (RuntimeException)
cause.getCause();
assertEquals("Wrong runtime exception", "Got an error",
realCause.getMessage());
}
}
This one throws an NPE if run after other tests:
java.lang.NullPointerException
at
org.jruby.embed.jsr223.JRubyEngine.wrapException(JRubyEngine.java:110)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:93)
at org.jruby.embed.jsr223.JRubyEngine.eval(JRubyEngine.java:154)
But if run by itself, it passes.
The line it’s pointing at in wrapException is calling write() on a
null writer. I explicitly set both writers after discovering that
(previously I was relying on the default being sensible) but that
doesn’t seem to have fixed the issue either.
I will report this one as a bug and try to find a workaround.
TX