【问题标题】:NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/StopwatchNoSuchMethodError:com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch
【发布时间】:2015-03-04 13:20:56
【问题描述】:

我的应用程序抛出 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

【问题讨论】:

  • 看起来你的类路径中有不兼容的 jars。
  • 与 selenium 2.54.0 类似的问题,他们使用的是番石榴,但番石榴版本 14 不匹配

标签: java guava restlet apispark


【解决方案1】:

使用扩展名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 版本的来源,并可能在相应的依赖项中添加一个排除项。我希望它能解决您的问题...

希望对你有帮助, 蒂埃里

【讨论】:

  • 你使用的是org.restlet.jse org.restlet.gae 会一样吗?
  • 另外我已经排除了其他番石榴依赖,APISpark 库仍然不能与 GAE 一起使用这里是一个示例错误日志:pastekit.com/jRZAyY
  • 它在 Java GAE 开发服务器上对我有用...在这个级别上对你有用吗?还是只存在于 GAE 平台本身?
  • 我确实尝试了与我在此处粘贴的错误 pastekit.com/jRZAyY 相关的“解决方法”,现在我收到此错误:pastekit.com/joBAW 我希望您可以检查
  • 我在我的测试项目中尝试了你的 maven 配置,它在我的 GAE 开发服务器中运行。我使用 GAE 1.9.18。您能否提供一个小项目(例如在 github 存储库中),以便我可以重现您的问题并对其进行调试?谢谢!
【解决方案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>

【讨论】:

    【解决方案3】:

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

    javap -p Stopwatch.class
    

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

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

    【讨论】:

      【解决方案4】:

      参考NoSuchMethodError Oracle Documentation

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

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

      我认为你得到这个异常是因为你的类路径中有多个版本的这个 jar,并且由于 createStarted() 方法可以从 15.0 版本中获得,我想说你有它的另一个旧版本,可能是由于依赖问题。

      【讨论】:

      • 是的,我现在从目标 WEB-INF/lib 文件夹中看到两个番石榴,一个是 14,一个是 16.0.1,多么奇怪
      • 这就是问题所在! 14 是导致此异常的原因。
      【解决方案5】:

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

      【讨论】:

      • 您使用的最新版本是什么?
      【解决方案6】:

      在我的例子中,我的一个 Maven 依赖项选择了一个较新版本的 Guava (16.0.1),它显然没有这个方法。当我在 pom.xml 中添加对该依赖项的排除项时,我的另一个依赖项选择了旧(正确)版本的 Guava,然后它就可以工作了。

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

      【讨论】:

        猜你喜欢
        • 2019-01-26
        • 2020-05-01
        • 1970-01-01
        • 2017-12-08
        • 2018-02-12
        • 2018-01-18
        • 2018-05-26
        • 1970-01-01
        • 2015-08-03
        相关资源
        最近更新 更多