Skip to content

Instantly share code, notes, and snippets.

@drexin
Created July 15, 2011 12:06
Show Gist options
  • Save drexin/1084570 to your computer and use it in GitHub Desktop.
Save drexin/1084570 to your computer and use it in GitHub Desktop.
jruby-akka exception after hot swapping actor
import akka.actor._
import org.jruby.Ruby
import org.jruby.RubyClass
import org.jruby.RubyModule
import org.jruby.RubyObject
import org.jruby.anno.JRubyMethod
import org.jruby.anno.JRubyClass
import org.jruby.runtime.ObjectAllocator
import org.jruby.runtime.ThreadContext
import org.jruby.runtime.builtin.IRubyObject
import org.jruby.javasupport.JavaUtil
import org.jruby.runtime.Block
import org.jruby.runtime.Visibility._
@JRubyClass(name=Array("Actor"))
class AkkaUntypedActor(val runtime: Ruby, val klass: RubyClass) extends RubyObject(runtime, klass) {
var actor: ActorRef = null
protected class InnerUntypedActor(runtime: Ruby, context: ThreadContext, parent: RubyObject, block: Block) extends UntypedActor {
def onReceive(msg: Any) {
val args = Array(JavaUtil.convertJavaToRuby(runtime,msg))
parent.instance_exec(context, args, block)
}
}
@JRubyMethod(visibility = PRIVATE)
def initialize(context: ThreadContext, block: Block) = {
val self = this
actor = Actors.actorOf(new UntypedActorFactory() {
def create() = {
new InnerUntypedActor(context.getRuntime(), context, self, block)
}
})
this
}
@JRubyMethod(name=Array("reply"))
def replyUnsafe(context: ThreadContext, msg: IRubyObject) {
actor.replyUnsafe(msg)
}
@JRubyMethod(name=Array("send_request_reply"))
def sendRequestReply(context: ThreadContext, msg: IRubyObject) = {
JavaUtil.convertJavaToRuby(context.getRuntime(), actor !! (msg))
}
@JRubyMethod(name=Array("send_request_reply_future"))
def sendRequestReplyFuture(context: ThreadContext, msg: IRubyObject) = {
JavaUtil.convertJavaToRuby(context.getRuntime(), actor !!! (msg))
}
@JRubyMethod(name=Array("<<"))
def sendMesssage(context: ThreadContext, msg: IRubyObject) {
actor ! (msg)
}
@JRubyMethod
def stop(context: ThreadContext) {
actor.stop()
}
@JRubyMethod
def start(context: ThreadContext) {
actor.start()
}
@JRubyMethod(name=Array("hot_swap"))
def hotSwap(context: ThreadContext, block: Block) {
val parent = this
actor ! HotSwap( self => {
case msg => {
val args = Array(JavaUtil.convertJavaToRuby(runtime,msg))
parent.instance_exec(context, args, block)
}
})
}
}
object AkkaUntypedActor {
def createActorClass(runtime: Ruby, akkaModule: RubyModule) = {
val actorc = runtime.defineClassUnder("Actor", runtime.getObject(), ActorAllocator, akkaModule)
actorc.setReifiedClass(classOf[AkkaUntypedActor])
actorc.kindOf = new RubyModule.KindOf() {
override def isKindOf(obj: IRubyObject, aType: RubyModule) = {
obj.isInstanceOf[AkkaUntypedActor]
}
}
actorc.defineAnnotatedMethods(classOf[AkkaUntypedActor])
actorc
}
object ActorAllocator extends ObjectAllocator() {
def allocate(runtime: Ruby, klass: RubyClass) = {
new AkkaUntypedActor(runtime, klass)
}
}
}
jruby-1.6.3 :001 > require 'lib/jruby-akka'
=> true
jruby-1.6.3 :002 > a = Akka::Actor.new do |m|
jruby-1.6.3 :003 > puts m
jruby-1.6.3 :004?> end
Can't load 'akka.conf'.
One of the three ways of locating the 'akka.conf' file needs to be defined:
1. Define the '-Dakka.config=...' system property option.
2. Put the 'akka.conf' file on the classpath.
3. Define 'AKKA_HOME' environment variable pointing to the root of the Akka distribution.
I have no way of finding the 'akka.conf' configuration file.
Using default values everywhere.
=> #<Akka::Actor:0x31455cf4>
jruby-1.6.3 :005 > a.start
=> nil
jruby-1.6.3 :006 > a << :foo
=> nil
foo
jruby-1.6.3 :007 > a.hot_swap do |m|
jruby-1.6.3 :008 > puts "swapped #{m}"
jruby-1.6.3 :009?> end
=> nil
jruby-1.6.3 :010 > a << :foo
=> nil
swapped foo
Java::JavaLang::NullPointerException:
from org.jruby.runtime.scope.NoVarsDynamicScope.setValue(NoVarsDynamicScope.java:87)
from org.jruby.runtime.scope.NoVarsDynamicScope.setValue(NoVarsDynamicScope.java:87)
from org.jruby.ast.DAsgnNode.interpret(DAsgnNode.java:110)
from org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104)
from org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
from org.jruby.ast.RescueNode.executeBody(RescueNode.java:216)
from org.jruby.ast.RescueNode.interpretWithJavaExceptions(RescueNode.java:120)
from org.jruby.ast.RescueNode.interpret(RescueNode.java:110)
from org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
from org.jruby.ast.NewlineNode.interpret(NewlineNode.java:104)
from org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
from org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
from org.jruby.runtime.InterpretedBlock.evalBlockBody(InterpretedBlock.java:374)
from org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:295)
from org.jruby.runtime.InterpretedBlock.yieldSpecific(InterpretedBlock.java:229)
from org.jruby.runtime.Block.yieldSpecific(Block.java:99)
... 85 levels...
from org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
from org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
from org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:190)
from org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:179)
from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:312)
from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:169)
from Users.corpsi.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_3.bin.jirb.__file__(/Users/corpsi/.rvm/rubies/jruby-1.6.3/bin/jirb:17)
from Users.corpsi.$_dot_rvm.rubies.jruby_minus_1_dot_6_dot_3.bin.jirb.load(/Users/corpsi/.rvm/rubies/jruby-1.6.3/bin/jirb)
from org.jruby.Ruby.runScript(Ruby.java:671)
from org.jruby.Ruby.runNormally(Ruby.java:575)
from org.jruby.Ruby.runFromMain(Ruby.java:424)
from org.jruby.Main.doRunFromMain(Main.java:278)
from org.jruby.Main.internalRun(Main.java:198)
from org.jruby.Main.run(Main.java:164)
from org.jruby.Main.run(Main.java:148)
from org.jruby.Main.main(Main.java:128)jruby-1.6.3 :011 >
@DLSieving
Copy link

I got the same error, namely:

   NoVarsDynamicScope.java:87:in `setValue': java.lang.NullPointerException

simply by typing:

   jruby -S warble -T

after porting my JRuby servlet development environment from Ubuntu 12.04 to Fedora 14 using all of the same revisions of all of the same gems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment