NoSuchMethodError:com.google.common.base.Stopwatch.createStarted()Lcom / google / common / base / Stopwatch

时间:2015-03-04 13:20:56

标签: java guava restlet apispark

我的应用正在抛出NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch错误。不知道为什么,因为16.0.1包含那个类,我已经检查过了。根据我的研究,看起来这是一个错误?

我也有这个代码用于参考,但我认为这不是问题:

    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$1.load(PeriodicFirewallCounterRule.java:86)
[INFO]  at org.restlet.ext.apispark.internal.firewall.rule.PeriodicFirewallCounterRule$1.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

6 个答案:

答案 0 :(得分:5)

使用扩展名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,你应该确定这个旧的番石榴版本来自哪里,并且可能在相应的依赖项中添加一个排除。我希望它能解决你的问题...

希望能帮到你, 亨利

答案 1 :(得分:2)

这是解决错误的解决方案:

首先排除旧的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>

答案 2 :(得分:1)

由该ClassLoader加载的类秒表不包含该方法,不确定是否由Jens所说的多个不兼容的jar引起,或仅仅因为16.0.1没有真正拥有该方法。 一个简单的检查是用javap或反编译器解析类:

javap -p Stopwatch.class

然后检查是否列出了该方法。

编辑:这个方法从15.0开始就存在,所以我也会检查你的类路径的内容。

答案 3 :(得分:1)

参考NoSuchMethodError Oracle Documentation

如果应用程序试图调用类的指定方法(静态或实例),并且该类不再具有该方法的定义,则抛出NoSuchMethodError:

通常,编译器会捕获此错误; 此错误只能在运行时发生,如果类的定义发生了不兼容的更改

我认为你有这个例外,因为你的类路径中有这个jar的多个版本,并且因为createStarted()版本可以使用15.0方法,我可以说你有另一个旧版本,可能是由于依赖问题。

答案 4 :(得分:0)

转移到最新版本的Guava为我做了

答案 5 :(得分:0)

在我的情况下,我的一个Maven依赖项正在挑选一个新版本的Guava(16.0.1),显然没有这个方法。当我在我的pom.xml中添加了对该依赖项的排除时,而我的另一个依赖项拾取了一个较旧的(正确的)Guava版本,然后就可以了。

您可以通过mvn dependency:tree打印您的依赖关系树,然后查看提取新版番石榴的内容来找到这一点。您可能需要添加多个排除项才能使其正确。