NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
我的应用程序抛出 NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
错误。不知道为什么,因为 16.0.1 确实包含 class,我已经检查过了。根据我的研究,这似乎是一个错误?
我也有这个代码供参考,虽然我认为这不是问题所在:
FirewallRule rule = new PeriodicFirewallCounterRule(60, TimeUnit.SECONDS, new IpAddressCountingPolicy());
((PeriodicFirewallCounterRule)rule).addHandler(new RateLimitationHandler(new UniqueLimitPolicy(10)));
FirewallFilter firewallFiler = new FirewallFilter(getContext(), list(rule));
firewallFiler.setNext(ma);
我的应用正在使用 Restlet APISpark:
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${version.restlet}</version>
</dependency>
当 运行 访问应用程序的 REST api 时,它抛出这个
错误:
[INFO] Caused by: java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.counter.PeriodicCounter.<init>(PeriodicCounter.java:65)
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.PeriodicFirewallCounterRule.load(PeriodicFirewallCounterRule.java:86)
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.PeriodicFirewallCounterRule.load(PeriodicFirewallCounterRule.java:84)
[INFO] at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3599)
[INFO] at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2379)
[INFO] at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2342)
[INFO] at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2257)
[INFO] ... 74 more
由该 ClassLoader 加载的 class 秒表不包含该方法,不确定是否如 Jens 所说是由多个不兼容的 jar 引起的,或者仅仅是因为 16.0.1 确实没有该方法。
一个简单的检查是用 javap 或反编译器解析 class:
javap -p Stopwatch.class
然后检查是否列出了该方法。
编辑:该方法从 15.0 开始就存在,所以我也会检查您 classpath 的内容。
参考NoSuchMethodError Oracle Documentation:
如果应用程序试图调用 class(静态或实例)的指定方法,并且 class 不再具有该方法的定义,则抛出 NoSuchMethodError:
方法。
通常情况下,这个错误会被编译器捕获; 如果 class 的定义发生了不兼容的更改,此错误只会在 运行 时发生。
我认为你得到这个异常是因为你的 class 路径中有这个 jar 的多个版本,并且因为 createStarted()
方法可从 15.0
版本 I谁会说你有它的另一个旧版本,可能是由于依赖性问题。
使用扩展 org.restlet.ext.apispark
时,检索到的 guava 依赖项的版本为 16.0.1
。
Downloading: http://maven.restlet.com/com/google/guava/guava/16.0.1/guava-16.0.1.jar
Downloading: http://repo.maven.apache.org/maven2/com/google/guava/guava/16.0.1/guava-16.0.1.jar
Downloaded: http://repo.maven.apache.org/maven2/com/google/guava/guava/16.0.1/guava-16.0.1.jar (2176 KB at 711.7 KB/sec)
它包含在使用以下 Maven 配置从头开始创建的应用程序中:
<project (...)>
<modelVersion>4.0.0</modelVersion>
<groupId>org.restlet</groupId>
<artifactId>restlet-apispark-firewall</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>
<version>1.0.0-snapshot</version>
<properties>
<java-version>1.7</java-version>
<restlet-version>2.3.1</restlet-version>
</properties>
<dependencies>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>${restlet-version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${restlet-version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven-restlet</id>
<name>Public online Restlet repository</name>
<url>http://maven.restlet.com</url>
</repository>
</repositories>
</project>
我集成了您的代码,在我这边运行良好。没有抛出异常...
我认为旧版本的 Guava 来自另一个依赖项。如果你使用 Maven,你应该确定这个旧的 guava 版本来自哪里,并可能在相应的依赖项中添加一个排除项。我希望它能解决您的问题...
希望对你有帮助,
蒂埃里
这是修复错误的解决方案:
首先排除旧的Guava
依赖然后:
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${version.restlet}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
迁移到最新版本的 Guava 对我来说很成功
在我的例子中,我的 Maven 依赖项之一是选择更新版本的 Guava (16.0.1),它显然没有这种方法。当我在我的 pom.xml
中为该依赖项添加一个排除项时,我的另一个依赖项选择了一个较旧(正确)版本的 Guava 然后它起作用了。
您可以通过 mvn dependency:tree
打印您的依赖关系树找到它,然后查看正在获取更新版本的番石榴的内容。您可能需要添加多个排除项才能正确处理。
我的应用程序抛出 NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
错误。不知道为什么,因为 16.0.1 确实包含 class,我已经检查过了。根据我的研究,这似乎是一个错误?
我也有这个代码供参考,虽然我认为这不是问题所在:
FirewallRule rule = new PeriodicFirewallCounterRule(60, TimeUnit.SECONDS, new IpAddressCountingPolicy());
((PeriodicFirewallCounterRule)rule).addHandler(new RateLimitationHandler(new UniqueLimitPolicy(10)));
FirewallFilter firewallFiler = new FirewallFilter(getContext(), list(rule));
firewallFiler.setNext(ma);
我的应用正在使用 Restlet APISpark:
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${version.restlet}</version>
</dependency>
当 运行 访问应用程序的 REST api 时,它抛出这个 错误:
[INFO] Caused by: java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch;
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.counter.PeriodicCounter.<init>(PeriodicCounter.java:65)
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.PeriodicFirewallCounterRule.load(PeriodicFirewallCounterRule.java:86)
[INFO] at org.restlet.ext.apispark.internal.firewall.rule.PeriodicFirewallCounterRule.load(PeriodicFirewallCounterRule.java:84)
[INFO] at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3599)
[INFO] at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2379)
[INFO] at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2342)
[INFO] at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2257)
[INFO] ... 74 more
由该 ClassLoader 加载的 class 秒表不包含该方法,不确定是否如 Jens 所说是由多个不兼容的 jar 引起的,或者仅仅是因为 16.0.1 确实没有该方法。 一个简单的检查是用 javap 或反编译器解析 class:
javap -p Stopwatch.class
然后检查是否列出了该方法。
编辑:该方法从 15.0 开始就存在,所以我也会检查您 classpath 的内容。
参考NoSuchMethodError Oracle Documentation:
如果应用程序试图调用 class(静态或实例)的指定方法,并且 class 不再具有该方法的定义,则抛出 NoSuchMethodError:
方法。
通常情况下,这个错误会被编译器捕获; 如果 class 的定义发生了不兼容的更改,此错误只会在 运行 时发生。
我认为你得到这个异常是因为你的 class 路径中有这个 jar 的多个版本,并且因为 createStarted()
方法可从 15.0
版本 I谁会说你有它的另一个旧版本,可能是由于依赖性问题。
使用扩展 org.restlet.ext.apispark
时,检索到的 guava 依赖项的版本为 16.0.1
。
Downloading: http://maven.restlet.com/com/google/guava/guava/16.0.1/guava-16.0.1.jar
Downloading: http://repo.maven.apache.org/maven2/com/google/guava/guava/16.0.1/guava-16.0.1.jar
Downloaded: http://repo.maven.apache.org/maven2/com/google/guava/guava/16.0.1/guava-16.0.1.jar (2176 KB at 711.7 KB/sec)
它包含在使用以下 Maven 配置从头开始创建的应用程序中:
<project (...)>
<modelVersion>4.0.0</modelVersion>
<groupId>org.restlet</groupId>
<artifactId>restlet-apispark-firewall</artifactId>
<name>${project.artifactId}</name>
<packaging>jar</packaging>
<version>1.0.0-snapshot</version>
<properties>
<java-version>1.7</java-version>
<restlet-version>2.3.1</restlet-version>
</properties>
<dependencies>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>${restlet-version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${restlet-version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>maven-restlet</id>
<name>Public online Restlet repository</name>
<url>http://maven.restlet.com</url>
</repository>
</repositories>
</project>
我集成了您的代码,在我这边运行良好。没有抛出异常...
我认为旧版本的 Guava 来自另一个依赖项。如果你使用 Maven,你应该确定这个旧的 guava 版本来自哪里,并可能在相应的依赖项中添加一个排除项。我希望它能解决您的问题...
希望对你有帮助, 蒂埃里
这是修复错误的解决方案:
首先排除旧的Guava
依赖然后:
<dependency>
<groupId>org.restlet.gae</groupId>
<artifactId>org.restlet.ext.apispark</artifactId>
<version>${version.restlet}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.1</version>
</dependency>
迁移到最新版本的 Guava 对我来说很成功
在我的例子中,我的 Maven 依赖项之一是选择更新版本的 Guava (16.0.1),它显然没有这种方法。当我在我的 pom.xml
中为该依赖项添加一个排除项时,我的另一个依赖项选择了一个较旧(正确)版本的 Guava 然后它起作用了。
您可以通过 mvn dependency:tree
打印您的依赖关系树找到它,然后查看正在获取更新版本的番石榴的内容。您可能需要添加多个排除项才能正确处理。