为什么 OSGI 与 ActorSystemActivator 的捆绑在启动时因 Logger 超时而失败?
Why does OSGI bundle with ActorSystemActivator fail with Logger timeout upon start?
我使用 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
class,利用 ActorSystemActivator
提供的默认 start
和 stop
方法。 Activator
class 代码如下所示:
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)环境中,我在 config.ini
中设置了 bootdelegation
,如官方 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$$anonfun$apply.applyOrElse(Logging.scala:114)
at akka.event.LoggingBus$$anonfun$$anonfun$apply.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 噩梦......
我错过了什么?
sschaef(谢谢)所附link中的信息帮助解决了这个问题。这是一种解决方法,可以在不破解依赖库的情况下启动 Akka 系统。如该线程中所述,显然是 class 加载程序问题,解决方案(我遵循的)使用侦听器来激活系统。
我仍然扩展了 ActorSystemActivator(虽然这可以避免,正如 sschaef 所指出的那样)并且我在重写的启动和停止方法中重用了扩展 class 中的代码。这是对我有用的代码:
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())
}
}
我使用 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
class,利用 ActorSystemActivator
提供的默认 start
和 stop
方法。 Activator
class 代码如下所示:
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)环境中,我在 config.ini
中设置了 bootdelegation
,如官方 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$$anonfun$apply.applyOrElse(Logging.scala:114)
at akka.event.LoggingBus$$anonfun$$anonfun$apply.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 噩梦...... 我错过了什么?
sschaef(谢谢)所附link中的信息帮助解决了这个问题。这是一种解决方法,可以在不破解依赖库的情况下启动 Akka 系统。如该线程中所述,显然是 class 加载程序问题,解决方案(我遵循的)使用侦听器来激活系统。
我仍然扩展了 ActorSystemActivator(虽然这可以避免,正如 sschaef 所指出的那样)并且我在重写的启动和停止方法中重用了扩展 class 中的代码。这是对我有用的代码:
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())
}
}