使用JRuby和Akka创建对远程服务的访问

时间:2016-10-17 18:56:46

标签: ruby akka jruby

我正在尝试让Akka actor连接到远程服务但是我无法访问我的UntypedActor中的Akka上下文。我的代码如下:

require 'java'

[
    'vendor/scala-library-2.11.8.jar',
    'vendor/akka/akka-actor_2.11-2.3.15.jar',
    'vendor/akka/config-1.2.1.jar'
].each { |lib| $CLASSPATH << lib }

java_import 'java.io.Serializable'

java_import 'akka.actor.ActorContext'
java_import 'akka.actor.UntypedActor'
java_import 'akka.actor.Actor'
java_import 'akka.actor.ActorRef'
java_import 'akka.actor.ActorSystem'
java_import 'akka.actor.UntypedActorFactory'
java_import 'akka.actor.ReceiveTimeout'
java_import 'akka.actor.SupervisorStrategy'

java_import 'akka.routing.RoundRobinRouter'
java_import 'akka.actor.Props'
java_import 'java.lang.System'
java_import 'scala.concurrent.duration.Duration'
java_import 'java.util.concurrent.TimeUnit'
java_import 'akka.japi.Creator'
java_import 'akka.japi.Procedure'

java_import 'akka.pattern.Patterns'

class Greeting
    include Serializable

    attr_reader :who

    def initialize (who)
        @who = who
    end
end

class GreetingActor < UntypedActor
  class << self
      alias_method :apply, :new
      alias_method :create, :new
  end

  def initialize ()
      remote = context.actorSelection("akka.tcp://Acquire@localhost:2552/user/acquire-service")
  end

  def onReceive (message)
      puts "Hello " + message.who
  end
end

class GreetingActorFactory
    include UntypedActorFactory

    def create
        GreetingActor.new
    end
end

在我的应用程序控制器中进行测试我有:

system = ActorSystem.create("GreetingSystem")
actor = system.actorOf(Props.create(GreetingActorFactory.new))

当我连接到我的服务器时,初始化会抛出以下内容:

[ERROR] [10/17/2016 14:53:46.943] [GreetingSystem-akka.actor.default-dispatcher-2] [akka://GreetingSystem/user/$a] null
akka.actor.ActorInitializationException: exception during creation
    at akka.actor.ActorInitializationException$.apply(Actor.scala:166)
    at akka.actor.ActorCell.create(ActorCell.scala:596)
    at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:456)
    at akka.actor.ActorCell.systemInvoke(ActorCell.scala:478)
    at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:263)
    at akka.dispatch.Mailbox.run(Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.NullPointerException
    at java.lang.reflect.Method.invoke(java/lang/reflect/Method.java:498)
    at org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(org/jruby/javasupport/JavaMethod.java:438)
    at org.jruby.javasupport.JavaMethod.invokeDirect(org/jruby/javasupport/JavaMethod.java:302)
    at RUBY.initialize(/Volumes/Work/SSEA/ADTE/app/classes/greeting.rb:47)
    at org.jruby.RubyClass.newInstance(org/jruby/RubyClass.java:994)
    at org.jruby.RubyClass$INVOKER$i$newInstance_DBG.call(org/jruby/RubyClass$INVOKER$i$newInstance_DBG.gen)
    at RUBY.create(/Volumes/Work/SSEA/ADTE/app/classes/greeting.rb:59)
    at GreetingActorFactory_1658069735.create(GreetingActorFactory_1658069735.gen:13)
    at akka.actor.CreatorConsumer.produce(akka/actor/Props.scala:338)
    at akka.actor.Props.newActor(akka/actor/Props.scala:255)
    at akka.actor.ActorCell.newActor(akka/actor/ActorCell.scala:552)
    at akka.actor.ActorCell.create(akka/actor/ActorCell.scala:578)
    at akka.actor.ActorCell.invokeAll$1(akka/actor/ActorCell.scala:456)
    at akka.actor.ActorCell.systemInvoke(akka/actor/ActorCell.scala:478)
    at akka.dispatch.Mailbox.processAllSystemMessages(akka/dispatch/Mailbox.scala:263)
    at akka.dispatch.Mailbox.run(akka/dispatch/Mailbox.scala:219)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(akka/dispatch/AbstractDispatcher.scala:397)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(scala/concurrent/forkjoin/ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(scala/concurrent/forkjoin/ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(scala/concurrent/forkjoin/ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(scala/concurrent/forkjoin/ForkJoinWorkerThread.java:107)

如果我注释掉这一行,一切都很好,所以我假设它是试图访问应该通过Akka UntypedActor提供的Akka上下文。我也尝试将其更改为getContext(),但仍无济于事。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

事实证明,在完全创建actor之前,您无法访问上下文。我最后添加了一个设置远程actor的方法,然后从我的工厂调用它。

form

在我的工厂:

def connect
    remote = get_context.actorSelection("akka.tcp://Acquire@127.0.0.1:2552/user/acquire-service")
end