已排查依赖冲突:Guava20.0下Stopwatch相关NoSuchMethodError求助
java.lang.NoSuchMethodError with Guava Stopwatch in gRPC I previously found a related Stack Overflow thread, but the solutions there didn't work for me. Here's the issue I'm facing:
java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createUnstarted()Lcom/google/common/base/Stopwatch
The exception is thrown from this code:
at io.grpc.internal.GrpcUtil$4.get(GrpcUtil.java:566) at io.grpc.internal.GrpcUtil$4.get(GrpcUtil.java:563)
I'm building my project with Maven, and it seems like there's only Guava 20.0 in the classpath with no obvious old version conflicts. Here's a snippet from mvn dependency:tree output:
[INFO] | +- com.google.cloud:google-cloud-core:jar:1.29.0:compile [INFO] | | +- com.google.guava:guava:jar:20.0:compile [INFO] | | +- com.google.http-client:google-http-client:jar:1.23.0:compile
This is the only Guava entry when I search dependencies, and the generated WAR in the target directory only has guava-20.jar under WEB-INF/lib—no duplicate dependencies are visible. I'd appreciate any suggestions to fix this.
Hey there, let's work through this issue step by step. Even though your Maven dependency tree and WAR lib folder look clean, there are a few sneaky places an old Guava version (or compatibility quirks) might be hiding:
- Check your application server's provided libraries: If you're deploying to a server like Tomcat, Jetty, or WildFly, the server itself might supply an older Guava version that overrides your project's 20.0. Verify this by:
- Checking the server's core
libdirectory for anyguava-*.jarfiles - Configuring your app to prioritize its own libraries (for Tomcat, you can use a
WEB-INF/tomcat-libdirectory or tweakloader.xmlto enforce app-classpath precedence)
- Checking the server's core
- Dig deeper into transitive dependencies: Run
mvn dependency:tree -Dverboseto see every single transitive dependency, including those that might be excluded but still pulled in via another path. Also, check if build plugins (like Maven Surefire) are using an older Guava version that leaks into your runtime classpath. - Log the runtime classpath: Add the JVM flag
-verbose:classwhen starting your app. This will log every class being loaded, along with the JAR it comes from. Look forcom.google.common.base.Stopwatchin the logs—this will tell you exactly which Guava JAR is being used at runtime, even if it's not in your WAR. - Upgrade your Guava version: Guava 20.0 is quite old (released in 2017). While
createUnstarted()was added in Guava 15.0, there might be compatibility gaps with your gRPC version. Check your gRPC dependency's docs for the recommended Guava version—newer gRPC releases work well with Guava 28.0 or later. - Check for shaded/repackaged JARs: Some dependencies shade Guava into their own JARs (certain Google Cloud libraries do this, though your
google-cloud-core:1.29.0uses Guava 20). Usejar tf <dependency-jar-path>on your dependencies to see if any containcom.google.common.base.Stopwatch—a shaded version here could conflict with your top-level Guava.
Let me know if any of these steps help you track down the root cause!
内容的提问来源于stack exchange,提问作者HK15

