7

My app is throwing NoSuchMethodError: com.google.common.base.Stopwatch.createStarted()Lcom/google/common/base/Stopwatch error. Not sure why, because 16.0.1 do contain that class, I've checked. From what I have researched, it looks like this is a bug?

I also have this code for refernence, though I think this is not the issue:

    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);

My app is using Restlet APISpark:

  <dependency>
      <groupId>org.restlet.gae</groupId>
      <artifactId>org.restlet.ext.apispark</artifactId>
      <version>${version.restlet}</version>
  </dependency>

When running and accessing the REST api of the app, it throws this error:

[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
quarks
  • 33,478
  • 73
  • 290
  • 513

6 Answers6

5

When using the extension org.restlet.ext.apispark, the guava dependency retrieved has the version 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)

It comes within an application created from scratch with the following maven configuration:

<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>

I integrated your code and it works fine on my side. No exception is thrown...

I think that an older version of Guava comes from another dependency. If you use Maven, you should identify where this old guava version comes from and perhaps add an exclude within the corresponding dependency. I hope that it will fix your problem...

Hope that helps you, Thierry

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • You are using org.restlet.jse how about org.restlet.gae would it be the same? – quarks Mar 05 '15 at 11:59
  • Also I have excluded the other guava dependency, still APISpark library would not work with GAE here is a sample error log: http://pastekit.com/jRZAyY – quarks Mar 05 '15 at 12:16
  • It's work for me on the Java GAE development server... Does it work for you at this level? Or is it only on the GAE platform itself? – Thierry Templier Mar 05 '15 at 13:38
  • I did try a "work around" relating to the error I pasted here http://pastekit.com/jRZAyY now I am getting this error: http://www.pastekit.com/joBAW I hope you can check – quarks Mar 06 '15 at 00:26
  • I tried your maven configuration within my test project and it works on my side in a GAE dev server. I use GAE 1.9.18. Could you provide me a small project (in a github repository for example) so I can reproduce your problem and debug it? Thanks! – Thierry Templier Mar 06 '15 at 08:21
  • I have fixed the problem with your tip (see my answer below) however the next issue is that the Firewall does not seem to work as a "firewall" I mean, even the resource is accessed simultaneously it does not throw "Too Many Request" error as expected – quarks Mar 06 '15 at 12:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/72409/discussion-between-thierry-templier-and-xybrek). – Thierry Templier Mar 06 '15 at 12:57
  • Pleased to hear that for your fix! I internally created an issue for the second part of your comment. I'll keep you posted here... – Thierry Templier Mar 06 '15 at 13:02
  • Thanks, yes no more error, I created a separate question for the new issue: http://stackoverflow.com/questions/28899855/limit-request-on-a-restlet-resource-with-apispark-restlet-extension – quarks Mar 06 '15 at 13:32
2

This is the solution that fixed the error:

First exclude old Guava dependency then:

  <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>
quarks
  • 33,478
  • 73
  • 290
  • 513
1

The class Stopwatch loaded by that ClassLoader does not contain that method, not sure if caused by multiple incompatible jars as Jens says or simply because 16.0.1 does not really have that method. A simple check will be to parse the class with javap or a decompiler:

javap -p Stopwatch.class

And then check if that method is listed.

Edit: That method is there since 15.0, so i'd check the content of you classpath too.

uraimo
  • 19,081
  • 8
  • 48
  • 55
1

Referring to NoSuchMethodError Oracle Documentation :

The NoSuchMethodError: is thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

Normally, this error is caught by the compiler; this error can only occur at run time if the definition of a class has incompatibly changed.

I think you got this Exception because you have more than one version of this jar in your classpath, and since the createStarted() method is available from the 15.0 version I whould say that you have an other old version of it, probably due to a dependency problem.

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
0

Moving to the latest version of Guava did it for me

jai
  • 321
  • 3
  • 9
0

In my case one of my Maven dependencies was picking up a newer version of Guava (16.0.1) that apparently does not have this method. When I added an exclusion to that dependency in my pom.xml, instead an older (correct) version of Guava was picked up by another of my dependencies and then it worked.

You can find this by printing your dependency tree via mvn dependency:tree and then looking at what is picking up the newer version of guava. You might need to add more than one exclusion to get it right.

Uncle Long Hair
  • 2,719
  • 3
  • 23
  • 33