2

我正在编写一个 Java Web 应用程序并放入 Tomcat 中运行。

当我尝试使用 JAR 中包含的方法时(我确信它包含我需要的方法),它显示:

java.lang.NoSuchMethodError: com.couchbase.client.CouchbaseClient.asyncGetBulk(Ljava/util/Collection;)Ljava

但是我尝试通过启动tomcat -verbose:class,我看到以下日志:

[Loaded net.spy.memcached.ops.VBucketAware from file:/.../apache-tomcat-5.5.30/webapps/.../WEB-INF/lib/spymemcached-2.8.2.jar]
[Loaded net.spy.memcached.protocol.binary.SingleKeyOperationImpl from file:/.../apache-tomcat-5.5.30/webapps/.../WEB-INF/lib/spymemcached-2.8.2.jar]
[Loaded net.spy.memcached.protocol.binary.GetOperationImpl from file:/.../apache-tomcat-5.5.30/webapps/.../WEB-INF/lib/spymemcached-2.8.2.jar]
Exception in thread "Thread-2139" java.lang.NoSuchMethodError: com.couchbase.client.CouchbaseClient.asyncGetBulk(Ljava/util/Collection;)Ljava/util/concurrent/Future

虽然 spymemcached-2.8.2.jar 包含该方法,所以我不明白为什么它会失败。

这就是我调用该方法的方式:

Future<Map<String,Object>> f = client.asyncGetBulk(key);

谢谢你的帮助。

更新1:

通过使用@Narendra Pathai 提供的代码,我得到了以下结果

[
file:/.../WEB-INF/classes/,
file:/.../WEB-INF/lib/activation-1.1.jar,
file:/.../WEB-INF/lib/commons-codec-1.5.jar,
file:/.../WEB-INF/lib/commons-lang-2.2.jar,
file:/.../WEB-INF/lib/commons-logging-1.1.1.jar,
file:/.../WEB-INF/lib/couchbase-client-1.0.3.jar,
file:/.../WEB-INF/lib/jaxb-api-2.1.jar,
file:/.../WEB-INF/lib/jaxb-impl-2.1.9.jar,
file:/.../WEB-INF/lib/jettison-1.1.jar,
file:/.../WEB-INF/lib/netty-3.2.0.Final.jar,
file:/.../WEB-INF/lib/runtime-0.4.1.5.jar,
file:/.../WEB-INF/lib/spymemcached-2.8.2.jar,
file:/.../WEB-INF/lib/stax-api-1.0-2.jar,
file:/.../WEB-INF/lib/xxx_core.jar,
file:/.../WEB-INF/lib/xxx_couchbase.jar
]

它们不包含具有com.couchbase.client.CouchbaseClient.asyncGetBulk 除 couchbase-client-1.0.3.jar 之外的路径的文件。

更新 2:

通过使用代码:

CodeSource codeSource = CouchbaseClient.class.getProtectionDomain().getCodeSource();
if (codeSource != null) {
    log.debug(codeSource.getLocation());
}

CodeSource codeSource2 = net.spy.memcached.MemcachedClient.class.getProtectionDomain().getCodeSource();
if (codeSource2 != null) {
    log.debug(codeSource2.getLocation());
}

我得到了以下结果:

file:/.../WEB-INF/lib/couchbase-client-1.0.3.jar
file:/.../WEB-INF/lib/spymemcached-2.8.2.jar

看来他们也是正确的。

4

5 回答 5

2

问题是类路径

public static void main(String[] args) {
            URLClassLoader classLoader = (URLClassLoader)Main.class.getClassLoader();
            System.out.println(Arrays.toString(classLoader.getURLs()));
    }

在你的 Main 类中使用这个方法来找出所有 jar 依赖项是从哪里解决的。

查看类加载器是否正在加载旧版本的 jar

于 2012-11-30T09:17:39.183 回答
1

我有类似的问题,但使用我自己的库之一,但感谢@Narendra Pathai 提交的这段代码

        URLClassLoader classLoader = (URLClassLoader)Main.class.getClassLoader();
        System.out.println(Arrays.toString(classLoader.getURLs()));

我发现类路径正在使用我的库的一些非常旧的版本。

然后我清理了构建文件夹(因为我使用的是 gradle),一切都编译并运行正常。

于 2017-02-08T18:33:52.890 回答
0

可能有一个具有相同规范名称的类,它位于类路径的上层。

JVM 选择了第一个类并且没有找到需要的方法。检查您的类路径中是否有同一个库的多个版本

于 2012-11-30T09:16:53.287 回答
0

您是否尝试过将 Couchbase 依赖项放在 $TOMCAT_HOME/lib 中只是为了首先进行测试。

并将它们从您的 WAR 中删除

于 2012-11-30T15:07:20.477 回答
0

如果你用 运行你的jar java -Dloader.path='dependency_jar_dir',并且有多个不同版本的jar[例如:com.a.1.1.jar,com.a.1.2.jar],那就错了!

于 2019-05-08T06:06:13.953 回答