使用SLF4J + Logback的OSGi应用程序上的java.lang.LinkageError

时间:2016-02-02 00:01:46

标签: java maven osgi slf4j logback

我已经在作为OSGi包的Java(1.8)应用程序上用SLF4J + Logback替换了JUL日志记录。但是,在更换之后,我可以更长时间地运行它(请参阅下面的错误)。我使用的是Maven Bundle插件(BND),但我不是OSGi的专家。

14:21:09.846 [FelixStartLevel] ERROR o.p.o.framework.FrameworkSlf4jLogger - Error starting file:/myapp/target/distribution/bundles/myapp.jar
org.osgi.framework.BundleException: Activator start error in bundle myapp [10].
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2204) ~[org.apache.felix.main-4.4.1.jar:na]
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2072) ~[org.apache.felix.main-4.4.1.jar:na]
    at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1299) ~[org.apache.felix.main-4.4.1.jar:na]
    at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:304) [org.apache.felix.main-4.4.1.jar:na]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, org/slf4j/LoggerFactory, and the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:336) ~[slf4j-api-1.7.12.jar:1.7.12]
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:284) ~[slf4j-api-1.7.12.jar:1.7.12]
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:305) ~[slf4j-api-1.7.12.jar:1.7.12]
    at org.koolapi.ServiceLoaderModule.<clinit>(ServiceLoaderModule.java:35) ~[koolapi-3.7.4.jar:3.7.4.20150518-0134]
    at org.koolapi.apibinding.Manager.createInjector(Manager.java:99) ~[koolapi-3.7.4.jar:3.7.4.20150518-0134]
    at org.koolapi.apibinding.Manager.instatiateDocumentManager(Manager.java:197) ~[koolapi-3.7.4.jar:3.7.4.20150518-0134]
    at org.koolapi.apibinding.Manager.createDocumentManager(Manager.java:38) ~[koolapi-3.7.4.jar:3.7.4.20150518-0134]
    at org.myapp.app.Activator.loadConfiguration(Activator.java:21) ~[classes/:na]
    at org.myapp.app.Activator.start(Activator.java:45) ~[classes/:na]
    at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645) ~[org.apache.felix.main-4.4.1.jar:na]
    at org.apache.felix.framework.Felix.activateBundle(Felix.java:2154) ~[org.apache.felix.main-4.4.1.jar:na]
    ... 4 common frames omitted

关于依赖项:myapp依赖于parent-app,它取决于slf4j-api v1.7.12,guava v18,logback-core和logback-classic v1.1.3。所以我没有在myapp的pom.xml中明确设置这些依赖项。 myapp还有另一个关键依赖,即koolapi;这个OSGi包在其/ lib /文件夹中包含slf4j-api-1.7.10.jar,但其清单中没有Export-Package指令。

总的来说,我检查了所有捆绑包的清单(felix,guava,logback-core,logback-classic,slf4j-api,koolapi,parent-app),看看谁在使用/导出slf4j,只有logback-classic.jar显式导出org.slf4j.impl; version = 1.7.7。

有没有人对如何解决冲突有任何想法或建议?

任何帮助将不胜感激!非常感谢, 乔尔

1 个答案:

答案 0 :(得分:3)

错误意味着您创建了一种情况,其中一个类加载器具有来自多个定义类加载器的类型ILoggerFactory的可见性。这在Java中是不合法的,因此LinkageError

如果没有完整的捆绑内容和清单,很难确定诊断,但原因是可能 slf4j-api koolapi捆绑内的副本。像这样嵌入库除非类型通过导出类型上的方法签名泄漏出来。由于此泄漏,您的应用包会暴露给ILoggerFactory类型的多个副本。

修复应该相对简单:从slf4j-api.jar内删除koolapi并使koolapi将包导入为普通依赖项。