【问题标题】:How to initialize a FSM actor in Java?如何在 Java 中初始化 FSM 角色?
【发布时间】:2018-08-29 13:19:12
【问题描述】:

我有跟随状态机

包示例;

import akka.actor.*;

public class ActorOnFsm {
    public static enum State {
    FirstState,
    SecondState,
    ThirdState,
    FourthState
    }

    public static final class ServiceData {

    }


    public class ActorFSM extends AbstractFSM<State, ServiceData> { 
    {
        startWith(FirstState, new ServiceData());
        when(FirstState,
            matchEvent(SomeMessage.class,
                ServiceData.class,
                (powerOn, noData) ->
            goTo(SecondState)
            .replying(SecondState))
            );


        when(SecondState,
            matchEvent(SomeOtherMessage.class,
                ServiceData.class,
                (powerOn, noData) ->
            goTo(ThirdState)
            .replying(ThirdState))
            );

        when(FirstState,
            matchEvent(soemErrorMessage.class,
                ServiceData.class,
                (powerOn, noData) ->
            goTo(FourthState)
            .replying(FourthState))
            );

        initialize();
    }



    }
}

这是测试

package examples;

    import akka.testkit.javadsl.TestKit;
    import org.junit.AfterClass;
    import org.junit.BeforeClass;
    import org.junit.Test;
    import org.scalatest.junit.JUnitSuite;

    import akka.actor.ActorRef;
    import akka.actor.ActorSystem;
    import akka.actor.Props;


    public class ActorOnFsmTest  extends JUnitSuite {


      static ActorSystem system;

      @BeforeClass
      public static void setup() {
        system = ActorSystem.create();
      }

      @AfterClass
      public static void teardown() {
        TestKit.shutdownActorSystem(system);
        system = null;
      }

      @Test
      public void testIt() {
        new TestKit(system) {{
          final Props props = Props.create(ActorOnFsm.class);
          final ActorRef underTest = system.actorOf(props);
          underTest.tell(new someMessage(), getRef());
          expectMsg(null);

        }};
      }

    }

这会引发以下异常

java.lang.IllegalArgumentException: unknown actor creator [class examples.ActorOnFsm]
    at akka.actor.IndirectActorProducer$.apply(IndirectActorProducer.scala:62)
    at akka.actor.Props.producer(Props.scala:131)
    at akka.actor.Props.<init>(Props.scala:144)
    at akka.actor.AbstractProps.create(AbstractProps.scala:32)
    at akka.actor.AbstractProps.create$(AbstractProps.scala:32)
    at akka.actor.Props$.create(Props.scala:22)
    at akka.actor.AbstractProps.create(AbstractProps.scala:32)
    at akka.actor.AbstractProps.create$(AbstractProps.scala:32)
    at akka.actor.Props$.create(Props.scala:22)
    at akka.actor.Props.create(Props.scala)
    at examples.ActorOnFsmTest$1.<init>(ActorOnFsmTest.java:33)
    at examples.ActorOnFsmTest.testIt(ActorOnFsmTest.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

在 java 中初始化 FSM 角色的推荐方法是什么?

【问题讨论】:

  • 这是一个问题还是代码转储?你试过什么?
  • 这是一个转储,从文档中可以看出我是如何尝试学习它的,希望该示例有效
  • 该链接可能是我在 java 中发现的唯一完整示例

标签: java junit akka fsm


【解决方案1】:

您正在尝试创建一个演员 最终道具 props = Props.create(ActorOnFsm.class); 最终 ActorRef underTest = system.actorOf(props);

但是,ActorOnFsm 不是真正的演员,不是吗?你忘了从 AbstractActor 扩展它吗?

【讨论】:

  • 它没有扩展AbstractActor,看这里的文档doc.akka.io/docs/akka/current/fsm.html#overview,考虑到如何为测试创建actor?
  • 我想我是在问如何测试一个 FSM 演员?
  • 或者我如何向这个演员发送消息?
猜你喜欢
  • 2012-05-05
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
相关资源
最近更新 更多