Search code examples
javanullpointerexceptionjruby

NullPointerException while using jruby


I embed jruby script engine into my java program by using javax.script.ScriptEngineManager

I made some jruby code that end with do ~ end block, after running all code, NullPointerException occured. but code ends with any other statement, no exception occurs.

version : 1.7.19

Caused by: java.lang.NullPointerException
    at org.jruby.embed.variable.Argv.updateARGV(Argv.java:169)
    at org.jruby.embed.variable.Argv.retrieve(Argv.java:158)
    at org.jruby.embed.variable.VariableInterceptor.retrieve(VariableInterceptor.java:154)
    at org.jruby.embed.internal.BiVariableMap.retrieve(BiVariableMap.java:378)
    at org.jruby.embed.internal.EmbedEvalUnitImpl.run(EmbedEvalUnitImpl.java:124)

in ARGV.java updateARGV

if (vars.containsKey((Object)name)) {
    var = vars.getVariable((RubyObject)receiver.getRuntime().getTopSelf(), name);
        var.setRubyObject(argv);

vars.getVariable returned null because of isReceiverIdentical return false in BiVariableMap.java

if (var.isReceiverIdentical(receiver)) {
    return var;
}

In isReceiverIdentical, this method just compare receiver with BiVariable's receiver usgin '=='.

Is this jruby bug? Or do I have to do something for this? If you need more information about this problem, plz comment it!


I got ScriptEngine(engine) from ScriptEngineManager and set some java instance and method like this

engine.put("this", console);
engine.eval("$command = $this.java_method :command, [java.lang.String]");

here is my test ruby code. result and tab is java object that has some method return String and list.

result = $command.call "something to pass"
puts result.getMessage
tabular = result.getData

tabular.each do |tab|
  rows = tab.getRows
  rows.each do |row|
    puts row
  end
  puts tab.getColumnNames
end

Solution

  • I had created ruby type object in my java code by creating new Ruby object...

    This causes checking fail in updateARGV because a receiver that register variable in BiVariableMap and another receiver that update variable are different.

    So, I got a Ruby object from new ScriptingContainer(from it we can always get a same Ruby object if local context is singleton) and used it to create new ruby type object in my java code.

    Reference: https://github.com/jruby/jruby/wiki/RedBridge#Singleton