如何摆脱 grpc api 中对 CallCredentials2 的调用

Sha*_*eal 3 google-cloud-platform grpc google-cloud-dataproc grpc-java

我正在为一个类项目编写一些代码,该项目将作业发送到 GCP 中的 dataproc 集群。我最近遇到了一个奇怪的错误,但我无法理解它。错误如下:

Exception in thread "Thread-5" java.lang.NoClassDefFoundError: io/grpc/CallCredentials2
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at com.google.api.gax.grpc.GrpcCallContext.withCredentials(GrpcCallContext.java:160)
at com.google.api.gax.grpc.GrpcCallContext.withCredentials(GrpcCallContext.java:67)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:210)
at com.google.cloud.dataproc.v1.stub.GrpcJobControllerStub.create(GrpcJobControllerStub.java:130)
at com.google.cloud.dataproc.v1.stub.JobControllerStubSettings.createStub(JobControllerStubSettings.java:215)
at com.google.cloud.dataproc.v1.JobControllerClient.<init>(JobControllerClient.java:139)
at com.google.cloud.dataproc.v1.JobControllerClient.create(JobControllerClient.java:120)
at com.shayr.searchEngineGUI.searchEngineGUI.constructInvertedIndices(searchEngineGUI.java:509)
at com.shayr.searchEngineGUI.searchEngineGUI.access$0(searchEngineGUI.java:501)
at com.shayr.searchEngineGUI.searchEngineGUI$2.run(searchEngineGUI.java:474)
Caused by: java.lang.ClassNotFoundException: io.grpc.CallCredentials2
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    ... 22 more
Run Code Online (Sandbox Code Playgroud)

我的代码中触发此问题的行是:

JobControllerClient jobControllerClient = JobControllerClient.create(jobControllerSettings);
Run Code Online (Sandbox Code Playgroud)

我最初尝试查找有关 CallCredentials2 的更多信息,以找出导致问题的原因,但我找不到太多任何内容,除了该类是对 CallCredentials 类进行更改时的临时解决方法,并且 CallCredentials2 此后已被折旧。

我对 google api 的了解有些有限,所以我花了一段时间才弄清楚如何解决这个问题。我必须更改项目的依赖项之一,以便将“grpc-api-1.42.1.jar”更改为“grpc-api-1.41.0.jar”,因为 1.41 版本的 api 是实现的版本CallCredentials2 类。

因此,我的项目现在按预期工作,但我仍然不确定为什么我的代码调用已折旧的类,如果可能的话,我宁愿避免这种情况。有谁知道为什么会发生这种情况?我正在使用最近更新的依赖项,因此我不确定为什么会调用已折旧的类。以下是将 grpc 版本更改为 1.41.0 之前,我的 pom.xml 文件中列出的依赖项:

<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-storage</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-datastore</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-dataproc</artifactId>
    <version>2.2.0</version>
</dependency>
<dependency>
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.32.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

Eri*_*son 6

使用mvn dependency:tree你可以发现依赖树中混合了 grpc-java 1.41.0 和 1.42.1 版本。google-cloud-datastore:2.2.0 引入了 grpc-api:1.42.1,但其他依赖项引入了 grpc 版本 1.40.1。

grpc-java 建议始终使用requireUpperBoundDepsmaven-enforcer 来捕获 Maven 静默降级依赖项。

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>1.4.1</version>
    <executions>
      <execution>
        <id>enforce</id>
        <goals>
          <goal>enforce</goal>
        </goals>
        <configuration>
          <rules>
            <requireUpperBoundDeps/>
          </rules>
        </configuration>
      </execution>
    </executions>
  </plugin>
Run Code Online (Sandbox Code Playgroud)

添加它会显示许多故障,可以通过在 google-cloud-datastore 之后订购 google-cloud-storage 来修复这些故障。但修复降级并不能解决您的问题。

让我们看一下现在的版本(具有依赖关系重新排序):

$ mvn dependency:tree
[INFO] +- com.google.cloud:google-cloud-datastore:jar:2.2.0:compile
[INFO] |  +- io.grpc:grpc-api:jar:1.42.1:compile
[INFO] |  +- io.grpc:grpc-context:jar:1.42.1:compile
...
[INFO] +- com.google.cloud:google-cloud-dataproc:jar:2.2.0:compile
[INFO] |  +- io.grpc:grpc-stub:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-protobuf:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-protobuf-lite:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-auth:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-netty-shaded:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-core:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-alts:jar:1.40.1:compile
[INFO] |  +- io.grpc:grpc-grpclb:jar:1.40.1:compile
...
Run Code Online (Sandbox Code Playgroud)

这些版本仍然存在问题,因为 io.grpc:grpc-auth 1.40.1 完全需要 io.grpc:grpc-api 1.40.1,但我们使用的是 1.42.1。Maven可以检测到这种情况,但不可靠。

您可以通过重新排序依赖项并显式添加一些依赖项来强制升级来解决此问题,但这很乏味。Google Cloud建议使用 BOM(也在datastorestorage的文档中)来选择一致的版本。该<dependencyManagement>部分选择要使用的库的版本,但实际上并不依赖于它们。使用 BOM 时,无需显式指定 BOM 中的依赖项版本。

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>libraries-bom</artifactId>
      <version>24.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
<dependencies>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-datastore</artifactId>
  </dependency>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-storage</artifactId>
  </dependency>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-dataproc</artifactId>
  </dependency>
  <dependency><!-- not part of the BOM -->
    <groupId>com.google.api-client</groupId>
    <artifactId>google-api-client</artifactId>
    <version>1.32.2</version>
  </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)

现在我们可以看到一致的版本:

$ mvn dependency:tree
...
[INFO] +- com.google.cloud:google-cloud-datastore:jar:2.1.3:compile
[INFO] |  +- io.grpc:grpc-api:jar:1.41.0:compile
[INFO] |  +- io.grpc:grpc-context:jar:1.41.0:compile
...
[INFO] +- com.google.cloud:google-cloud-dataproc:jar:2.2.2:compile
[INFO] |  +- io.grpc:grpc-stub:jar:1.41.0:compile
[INFO] |  +- io.grpc:grpc-protobuf:jar:1.41.0:compile
[INFO] |  +- io.grpc:grpc-protobuf-lite:jar:1.41.0:compile
[INFO] |  +- io.grpc:grpc-alts:jar:1.41.0:runtime
[INFO] |  +- io.grpc:grpc-grpclb:jar:1.41.0:runtime
[INFO] |  +- io.grpc:grpc-auth:jar:1.41.0:runtime
[INFO] |  +- io.grpc:grpc-netty-shaded:jar:1.41.0:runtime
[INFO] |  +- io.grpc:grpc-core:jar:1.41.0:runtime
...
Run Code Online (Sandbox Code Playgroud)