错误?配置中指定的记录器无法加载[akka.testkit.TestEventListener]?

时间:2015-05-03 15:59:57

标签: java maven akka

根据docs,在(期待日志消息)下,

  

确保将默认记录器与TestEventListener进行交换   你的application.conf启用这个功能:akka.loggers =   [akka.testkit.TestEventListener]

因此,当我将它放在 application.conf 中时,这很有效。我的测试工作很顺利

@Test
public void testActorForNonExistentLocation() throws Exception {
  final Map<String, String> configValues = Collections.singletonMap("tenant.assetsLocation",
                                                                    "/non/existentLocation");
  final Config config = mergeConfig(configValues);
  System.out.println(config.getList("akka.loggers"));

  new JavaTestKit(system) {{
    assertEquals("system", system.name());

    final Props props = TenantMonitorActor.props(config);
    final ActorRef supervisor = system.actorOf(props, "supervisor");
    new EventFilter<Void>(DiskException.class) {

      @Override
      protected Void run() {
        supervisor.tell(new TenantMonitorMessage(), supervisor);
        return null;
      }
    }.from("akka://system/user/supervisor/diskMonitor").occurrences(1).exec();

  }};
}

现在,当我尝试运行我的应用程序时

public class Main {
  private Main() {
  }

  public static void main(final String[] args) {
    final Config config = ConfigFactory.load();
    final ActorSystem actorSystem = ActorSystem.create(config.getString("ec.name"));
    setUpMonitoring(actorSystem, config);
  }

  private static void setUpMonitoring(final ActorSystem system, final Config config) {
    final ActorRef tenantMonitorRef = system.actorOf(TenantMonitorActor.props(config),
                                                     "tenantMonitor");
    tenantMonitorRef.tell(new TenantMonitorMessage(), tenantMonitorRef);
  }
}

我看错了

error while starting up loggers
akka.ConfigurationException: Logger specified in config can't be loaded [akka.testkit.TestEventListener] due to [java.lang.ClassNotFoundException: akka.testkit.TestEventListener]
    at akka.event.LoggingBus$$anonfun$4$$anonfun$apply$1.applyOrElse(Logging.scala:116)
    at akka.event.LoggingBus$$anonfun$4$$anonfun$apply$1.applyOrElse(Logging.scala:115)
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
    at scala.util.Failure$$anonfun$recover$1.apply(Try.scala:215)
    at scala.util.Try$.apply(Try.scala:191)
    at scala.util.Failure.recover(Try.scala:215)
    at akka.event.LoggingBus$$anonfun$4.apply(Logging.scala:115)
    at akka.event.LoggingBus$$anonfun$4.apply(Logging.scala:110)
    at scala.collection.TraversableLike$WithFilter$$anonfun$map$2.apply(TraversableLike.scala:728)
    at scala.collection.Iterator$class.foreach(Iterator.scala:750)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1202)
    at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
    at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
    at scala.collection.TraversableLike$WithFilter.map(TraversableLike.scala:727)
    at akka.event.LoggingBus$class.startDefaultLoggers(Logging.scala:110)
    at akka.event.EventStream.startDefaultLoggers(EventStream.scala:26)
    at akka.actor.LocalActorRefProvider.init(ActorRefProvider.scala:622)
    at akka.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:619)
    at akka.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:616)
    at akka.actor.ActorSystemImpl._start(ActorSystem.scala:616)
    at akka.actor.ActorSystemImpl.start(ActorSystem.scala:633)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:142)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:109)
    at akka.actor.ActorSystem$.create(ActorSystem.scala:57)
    at akka.actor.ActorSystem.create(ActorSystem.scala)
    at Main.main(Main.java:16)
    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:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.ClassNotFoundException: akka.testkit.TestEventListener
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:67)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:66)
    at scala.util.Try$.apply(Try.scala:191)
    at akka.actor.ReflectiveDynamicAccess.getClassFor(DynamicAccess.scala:66)
    at akka.event.LoggingBus$$anonfun$4.apply(Logging.scala:113)
    ... 24 more
Exception in thread "main" akka.ConfigurationException: Could not start logger due to [akka.ConfigurationException: Logger specified in config can't be loaded [akka.testkit.TestEventListener] due to [java.lang.ClassNotFoundException: akka.testkit.TestEventListener]]
    at akka.event.LoggingBus$class.startDefaultLoggers(Logging.scala:144)
    at akka.event.EventStream.startDefaultLoggers(EventStream.scala:26)
    at akka.actor.LocalActorRefProvider.init(ActorRefProvider.scala:622)
    at akka.actor.ActorSystemImpl.liftedTree2$1(ActorSystem.scala:619)
    at akka.actor.ActorSystemImpl._start$lzycompute(ActorSystem.scala:616)
    at akka.actor.ActorSystemImpl._start(ActorSystem.scala:616)
    at akka.actor.ActorSystemImpl.start(ActorSystem.scala:633)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:142)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:109)
    at akka.actor.ActorSystem$.create(ActorSystem.scala:57)
    at akka.actor.ActorSystem.create(ActorSystem.scala)
    at Main.main(Main.java:16)
    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:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

我的 application.conf 看起来像

akka {
  event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
  loglevel = "INFO"
  loggers = [akka.testkit.TestEventListener]
}

ec {
  name = "Connector"
}

tenant {
  assetsLocation: /Users
}

monitoring {
  tenant.disk.schedule.seconds: 2
  tenant.disk.threshold.percent: 80
}

我也安装了依赖项

<dependencies>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-actor_2.11</artifactId>
    <version>${akka-actor_2.11.version}</version>
  </dependency>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-testkit_2.11</artifactId>
    <version>${akka-testkit_2.11.version}</version>
  </dependency>
</dependencies>

以及版本

<akka-actor_2.11.version>2.3.9</akka-actor_2.11.version>
<akka-testkit_2.11.version>2.3.10</akka-testkit_2.11.version>

错误/不一致在哪里?

可能根本不是一个错误,而且理解上有差异。

我们使用maven scopes来确定哪些依赖项应该可用以及何时可用。通常使用测试,我们使用<scope>test</scope>使依赖项仅在测试中可用,而不是在捆绑时在最终应用程序jar中。

现在,如果我们使用这种测试(期望日志消息),我们需要删除<scope>test</scope>以使应用程序正确运行并且测试同时通过。这意味着依赖性akka-testkit也需要出现在最终的jar中,因为 application.conf 需要加载akka.testkit.TestEventListener

如果所有声音都正确,则将生产和测试代码耦合在一起,并且在当前设置中是必需的。

同样,我可能已经遗漏了一些非常基本的东西,但是我可以运行应用程序并让测试通过的唯一方法是将依赖项akka-actorakka-testkit together结合起来。

你有什么想法?

1 个答案:

答案 0 :(得分:1)

在测试资源中添加application.conf:

src/test/resources/application.conf

内容可能如下:

include "../../main/resources/application"

akka.loggers = [akka.testkit.TestEventListener]

此application.conf仅在测试期间加载,因此您可以将akka-testkit依赖项的范围仅限于测试。