我刚尝试测试使用Apache Camel 2.10.3的应用程序,并且在实例化DefaultCamelContext
后立即获得以下异常:
java.lang.NoSuchMethodError: org.slf4j.Logger.trace(Ljava/lang/String;Ljava/lang/Object;)V
at org.apache.camel.impl.DefaultPackageScanClassResolver.<init>(DefaultPackageScanClassResolver.java:70)
at org.apache.camel.impl.DefaultCamelContext.<init>(DefaultCamelContext.java:222)
我确保slf4j-api-1.6.6
(这是Camel 2.10.3附带的)在运行时类路径上。接下来,我怀疑我可能还有其他依赖项也使用过SLF4J,但这依赖于它的不同版本。所以我打开了Eclipse,并运行了org.slf4j.Logger
的类型搜索。果然,我看到该类列在2个不同的JAR中:slf4j-api-1.6.6.jar
(正如预期的那样!)和另一个第三方jar,{{1 }}
所以我打开了widget-lib-3.0.jar
,看到SLF4J打包在里面就像这样:
widget-lib3.0.jar
没有办法说出它在这里使用的是什么版本的SLF4J,但是我愿意打赌它是一个早于1.6.x的版本,这是Camel 2.10.3想要的版本。
所以我最好的,稍微受过教育的猜测是,在运行时,JRE类加载器首先找到widget-lib-3.0/
com/
<Widget Lib's compiled classes>
org/
slf4j/
spi/
...
impl/
...
<A bunch of SLF4J classes, like LoggerFactory.class, etc.>
,然后加载它,然后它们将加载Camel JAR及其依赖项。然后,当widget-lib-3.0.jar#org/slf4j/Logger
调用SLF4J DefaultPackageScanClassResolver
方法时,它没有找到SLF4J的1.6.6版本,而是找到了trace(String,Object)
附带的任何版本,并且该方法/重载没有'存在。
我是否已离开基地?如果我离开基地,这对你意味着什么呢?如果我正在进行中,那么我提出的解决方案是在没有widget-lib-3.0.jar
包的情况下重新进行JAR widget-lib-3.0.jar
(不存在其他更现代的版本)。我的理论是org/slf4j
,它是向后兼容的,将是唯一加载的SLF4J版本,然后将适用于两个JAR。有什么想法吗?提前谢谢。
答案 0 :(得分:0)
“没有办法说出它在这里使用的SLF4J的版本,但我会 愿意打赌它是一个比1.6.x更早的版本 是Camel 2.10.3想要的......“
为什么不从widget-lib-3.0.jar反编译该类文件,看看是否存在所需的方法?
答案 1 :(得分:0)
你的方法是正确的。 SLF4J 1.x版本之间的API兼容。 (你顺便使用Maven吗?它旨在防止这种问题)。
什么是widget-lib
?是否有不包含其依赖项的版本?如果有,你应该使用它。
答案 2 :(得分:0)
我是否正在离开基地?
没有。看起来你正在这里。
确认它的方法是在窗口小部件库JAR中获取org.sfl4j.Logger
的副本,并使用javah
查看它是否具有void trace(String, Object)
方法。
确认后,有许多解决方案:
最干净的解决方案是获取窗口小部件库的源代码,根据您需要的sfl4j版本重新编译它,并构建新版本的JAR而不在其中嵌入sfl4j。 (您可能需要修改窗口小部件库的源,但不太可能)。
一个更简单的解决方案可能是确保您将更新的(并且应该是向后兼容的)slf4 API JAR放在类路径上的小部件库JAR之前。这样,小部件JAR中旧版本的slf4j将被较新的版本用“Camel”需要的额外方法“阴影”。