【发布时间】:2013-02-01 10:18:30
【问题描述】:
我刚刚尝试测试一个使用 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(如预期的那样!)和另一个 3rd 方 jar,widget-lib-3.0.jar。
所以我打开了widget-lib3.0.jar,看到里面的 SLF4J 是这样打包的:
widget-lib-3.0/
com/
<Widget Lib's compiled classes>
org/
slf4j/
spi/
...
impl/
...
<A bunch of SLF4J classes, like LoggerFactory.class, etc.>
没有办法知道它在这里使用的是什么版本的 SLF4J,但我敢打赌它是早于 1.6.x 的版本,这正是 Camel 2.10.3 想要的。
所以我最好的,稍微受过教育的猜测是,在运行时,JRE 类加载器首先找到widget-lib-3.0.jar#org/slf4j/Logger,加载它,然后然后他们去加载 Camel JAR 及其依赖项。然后,当DefaultPackageScanClassResolver 调用 SLF4J trace(String,Object) 方法时,它没有找到 1.6.6 版本的 SLF4J,而是找到了 widget-lib-3.0.jar 附带的任何版本,并且该方法/重载不存在。
我是否正在离开基地?如果我不在基地,这对你意味着什么,所以?如果我走上了正轨,那么我建议的解决方案是重新 JAR widget-lib-3.0.jar 而不包含 org/slf4j 包(不存在其他更现代的版本)。我的理论是向后兼容的slf4j-api-1.6.6 将是唯一被加载的 SLF4J 版本,然后适用于两个 JAR。有什么想法吗?提前致谢。
【问题讨论】:
标签: java jar classloader slf4j dll