Created
July 15, 2011 12:06
-
-
Save drexin/1084570 to your computer and use it in GitHub Desktop.
jruby-akka exception after hot swapping actor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 > |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I got the same error, namely:
simply by typing:
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.