Java App Engine 调用 GcsService.createOrReplace 在 Maven clean/build 和部署后导致 Stopwatch.createUnstarted noSuchMethodError

Java App Engine call to GcsService.createOrReplace results in Stopwatch.createUnstarted noSuchMethodError after Maven clean/build and deploy

我正在为我的 GAE Java 项目使用 Intellij 和 Maven。我在 Google 云存储中从 GcsService 调用 createOrReplace 时遇到一些奇怪的问题,这取决于我在我的项目中编辑单个文件。这是发生的事情:

我对 Github 进行了稳定的修订。我签出该修订版并使用 intellij 配置来部署该应用程序。我的部署如下所示: 在全新安装和构建之后,这是执行的命令:/Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -Dfile.encoding=UTF-8 -classpath /Users/me/.m2/repository/com/google/appengine/appengine-java-sdk/1.9.15/appengine-java-sdk/appengine-java-sdk-1.9.15/lib/appengine-tools-api.jar com.google.appengine.tools.admin.AppCfg --email=me@gmail.com --passin --no_cookies update /Users/me/git/blunka/harry-gcp/module-ear/target/module-ear-1.0

然后我向特定的源文件添加注释。我重新部署并注意到 /target 下的一堆输出文件已更改。我的应用现在因以下错误而损坏:

java.lang.NoSuchMethodError: com.google.common.base.Stopwatch.createUnstarted()Lcom/google/common/base/Stopwatch;
    at com.google.appengine.tools.cloudstorage.RetryHelper.runWithRetries(RetryHelper.java:156)
    at com.google.appengine.tools.cloudstorage.GcsServiceImpl.createOrReplace(GcsServiceImpl.java:70)

我现在删除该评论并重新部署。我执行 git status 并注意到 /target 下的一些更改文件不再存在。我的应用再次正常运行。

当我查看修改后的 class 的反编译 .class 文件时,它们是相同的。这是我抛出错误的模块的 dep 树:

[INFO] +- com.google.api-client:google-api-client-appengine:jar:1.19.0:compile
[INFO] |  \- com.google.api-client:google-api-client:jar:1.19.0:compile
[INFO] |     \- com.google.guava:guava-jdk5:jar:13.0:compile
[INFO] +- com.google.appengine.tools:appengine-gcs-client:jar:RELEASE:compile
[INFO] |  \- (com.google.guava:guava:jar:18.0:compile - omitted for duplicate)
[INFO] +- com.google.guava:guava:jar:18.0:compile
[INFO] \- com.googlecode.objectify:objectify:jar:5.1.1:compile
[INFO]    \- (com.google.guava:guava:jar:17.0:compile - omitted for conflict with 18.0)

我有几个问题:

  1. 为什么评论会导致我的输出文件发生变化?
  2. 即使反编译源相同,为什么评论中更改的输出文件会导致应用程序行为发生变化?
  3. 如果 guava (google.common.base) 有冲突,我该如何解决?
  4. 我怎样才能防止将来发生这样的事情?

抱歉 "stealing" 的回答,但@ben-manes 在他的评论中是正确的。我遇到了同样的问题,他的最后一条消息帮助了我。我只是想把它作为一个答案,因为不是每个人都会看评论。

google-api-client依赖于guava-jdk5,与appengine-gcs-client使用的guava-18+产生冲突

<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client-appengine</artifactId>
    <version>1.20.0</version>
    <exclusions>
        <!-- creates conflicts with another guava version in appengine-gcs-client -->
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava-jdk5</artifactId>
        </exclusion>
    </exclusions>
</dependency>