为什么与ActorSystemActivator绑定的OSGI会在启动时因Logger超时而失败?

时间:2015-01-06 21:04:50

标签: scala osgi akka

我使用akka-osgi_2.10-2.3.4库和所有必需的依赖项在Scala中编写了一个OSGI“Hello World”应用程序。实际上这里是所有依赖maven报告:

+- com.typesafe.akka:akka-actor_2.10:jar:2.3.4:compile
|  \- com.typesafe:config:jar:1.2.1:compile
+- com.typesafe.akka:akka-slf4j_2.10:jar:2.3.4:compile
|  \- org.slf4j:slf4j-api:jar:1.7.5:compile
+- org.apache.felix:org.osgi.core:jar:1.4.0:compile
+- com.typesafe.akka:akka-osgi_2.10:jar:2.3.4:compile
|  +- org.osgi:org.osgi.core:jar:4.3.1:compile
|  \- org.osgi:org.osgi.compendium:jar:4.3.1:compile
+- org.scala-lang:scala-library:jar:2.10.4:compile

该应用使用最简单的Activator类,该类利用start提供的默认stopActorSystemActivator方法。 Activator类代码如下所示:

import akka.actor.ActorSystem
import org.osgi.framework.BundleContext
import akka.osgi.ActorSystemActivator

class Activator extends ActorSystemActivator {

  def configure(bundleContext: BundleContext, system: ActorSystem): Unit = {
  }
}

我使用IBM JDK 1.7并在eclipse juno-64(在ubuntu 12.04上)环境中,我在bootdelegation中设置了config.ini,如官方documentation中所述:

org.osgi.framework.bootdelegation=sun.misc

我使用-console参数启动了Eclipse,并在OSGi框架中部署了捆绑的应用程序。这是我在OSGi控制台中运行ss时得到的结果:

426     <<LAZY>>    test-osgi_0.0.1.SNAPSHOT

我遇到的问题是启动捆绑包。当我尝试启动时:

osgi> start 426

我得到了Akka超时异常:

[WARN] [01/06/2015 15:04:02.530] [Gogo shell] [EventStream(akka://bundle-426-ActorSystem)] Logger log1-Logging$DefaultLogger did not respond within Timeout(25000 milliseconds) to InitializeLogger(bus)
error while starting up loggers
akka.ConfigurationException: Logger specified in config can't be loaded [akka.event.Logging$DefaultLogger] due to [akka.event.Logging$LoggerInitializationException: Logger log1-Logging$DefaultLogger did not respond with LoggerInitialized, sent instead [TIMEOUT]]
    at akka.event.LoggingBus$$anonfun$4$$anonfun$apply$1.applyOrElse(Logging.scala:114)
    at akka.event.LoggingBus$$anonfun$4$$anonfun$apply$1.applyOrElse(Logging.scala:113)
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33)
...

我在网上查了一下,发现了与我类似的问题,但没有一个建议的解决方案适合我。我尝试将默认记录器响应超时修改为不同的值,我将DefaultLogger更改为其他版本(DefaultOSGiLogger),我添加了 org.osgi.framework.system.packages.extra = sun.misc 配置,但没有任何帮助。 我也试过了akka-sample-osgi-dining-hakkers例子,但是我遇到了OSGi的噩梦...... 我错过了什么?

1 个答案:

答案 0 :(得分:1)

sschaef所附链接的信息(谢谢)帮助解决了这个问题。这是一种解决方法,可以在不破坏依赖库的情况下启动Akka系统。正如该线程中所提到的,显然是类加载器问题,并且解决方案(我遵循)使用侦听器来激活系统。

我仍然有扩展的ActorSystemActivator(虽然这可以像sschaef所指出的那样避免)并且我在重写的start和stop方法中重用了扩展类中的代码。以下代码对我有用:

class Activator extends ActorSystemActivator {

  private var system: Option[ActorSystem] = None
  @volatile var bundleListener: org.osgi.framework.BundleListener = null

  def configure(bundleContext: BundleContext, system: ActorSystem): Unit = {}
  override def getActorSystemName(context: BundleContext): String = "my-actor-system"

  override def start(context: BundleContext) = {
    bundleListener = new org.osgi.framework.BundleListener() {
      override def bundleChanged(event: org.osgi.framework.BundleEvent) {
        if (event.getBundle == context.getBundle) {
          if (event.getType == org.osgi.framework.BundleEvent.STARTED) {
            system = Some(OsgiActorSystemFactory(context, getActorSystemConfiguration(context)).createActorSystem(Option(getActorSystemName(context))))
            system foreach (addLogServiceListener(context, _))
            system foreach (configure(context, _))
          }
        }
      }
    }
    context.addBundleListener(bundleListener)
  }

  override def stop(context: BundleContext) = {
    if (bundleListener != null)
      context.removeBundleListener(bundleListener)
    system foreach (_.shutdown())
  }
}