java - 与 NameResolverProvider 相关的 gRPC 异常
问题描述
我有一个用 Java 编写的 gRPC 服务器,它试图通过具有项目所有者角色的服务帐户访问 Firestore 和其他服务。服务器成功运行了很多次,但是当我再次尝试运行时,发生了这种情况:
Exception in thread "main" java.util.ServiceConfigurationError: io.grpc.NameResolverProvider: Provider io.grpc.grpclb.SecretGrpclbNameResolverProvider$Provider could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at io.grpc.ServiceProviders.loadAll(ServiceProviders.java:67)
at io.grpc.NameResolverRegistry.getDefaultRegistry(NameResolverRegistry.java:101)
at io.grpc.internal.AbstractManagedChannelImplBuilder.<init>(AbstractManagedChannelImplBuilder.java:107)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<init>(NettyChannelBuilder.java:136)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.<init>(NettyChannelBuilder.java:131)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.forAddress(NettyChannelBuilder.java:117)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(NettyChannelProvider.java:37)
at io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider.builderForAddress(NettyChannelProvider.java:23)
at io.grpc.ManagedChannelBuilder.forAddress(ManagedChannelBuilder.java:39)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:270)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.access$1500(InstantiatingGrpcChannelProvider.java:71)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider$1.createSingleChannel(InstantiatingGrpcChannelProvider.java:202)
at com.google.api.gax.grpc.ChannelPool.create(ChannelPool.java:72)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:209)
at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:192)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:155)
at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:122)
at com.google.cloud.firestore.spi.v1.GrpcFirestoreRpc.<init>(GrpcFirestoreRpc.java:122)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreRpcFactory.create(FirestoreOptions.java:90)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreRpcFactory.create(FirestoreOptions.java:82)
at com.google.cloud.ServiceOptions.getRpc(ServiceOptions.java:561)
at com.google.cloud.firestore.FirestoreOptions.getFirestoreRpc(FirestoreOptions.java:385)
at com.google.cloud.firestore.FirestoreImpl.<init>(FirestoreImpl.java:67)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreFactory.create(FirestoreOptions.java:73)
at com.google.cloud.firestore.FirestoreOptions$DefaultFirestoreFactory.create(FirestoreOptions.java:66)
at com.google.cloud.ServiceOptions.getService(ServiceOptions.java:541)
at services.FirestoreServiceActions.<init>(FirestoreServiceActions.java:25)
at CNTextServer.main(CNTextServer.java:47)
Caused by: java.lang.VerifyError: Cannot inherit from final class
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 java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
at java.lang.Class.getConstructor0(Class.java:3075)
at java.lang.Class.newInstance(Class.java:412)
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
... 30 more
为了简化事情并解决 IntelliJ Idea 上可能发生的一些主要问题,我创建了一个更简单的 (Maven) 项目,它只有一些代码来启动服务器,它运行良好,服务器运行完美。虽然,当我添加初始化 Firestore 服务的行时,会引发相同的异常。
我有一个环境变量 (GOOGLE_APPLICATION_CREDENTIALS) 指向具有项目所有者角色的服务帐户的密钥,就像我之前提到的那样。我也尝试了 FileInputStream 替代方案,指向密钥,但没有成功。
我更简单的(Maven)项目的代码是:
private static final int SERVICE_PORT = 8000;
private Firestore firestoreService
public static void main(String[] args) {
try {
System.out.println("--> SETTING UP THE SERVER...");
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(SERVICE_ACCOUNT_KEY_PATH));
this.firestoreService = FirestoreOptions.newBuilder().setCredentials(credentials).build().getService();
Server service = ServerBuilder
.forPort(SERVICE_PORT)
.addService(new CNTextServer())
.build();
service.start();
System.out.println("--- SERVER STARTED. LISTENING ON PORT " + SERVICE_PORT);
System.out.println("--> PRESS 'ENTER' TO STOP THE SERVER");
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
System.out.println("<-- SERVER SHUTTING DOWN...");
service.shutdown();
} catch (Exception ex) {
System.out.println("### EXCEPTION ON SERVER.MAIN() ###\n" + ex.getMessage());
}
}
Maven pom.xml 文件的依赖项是:
<dependencies>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.28.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-firestore</artifactId>
<version>1.34.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>1.108.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>1.106.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-compute</artifactId>
<version>0.118.0-alpha</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vision</artifactId>
<version>1.99.3</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-translate</artifactId>
<version>1.94.5</version>
</dependency>
<dependency>
<groupId>leic.cn.li62d-g04</groupId>
<artifactId>CNTextContract</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/../CNTextContract/target/CNTextContract-1.0-SNAPSHOT.jar</systemPath>
</dependency>
</dependencies>
解决方案
运行mvn dependency:tree
我们看到:
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ examples ---
[INFO] com.example:examples:jar:1.0.0
[INFO] +- io.grpc:grpc-netty-shaded:jar:1.28.0:compile
[INFO] | \- io.grpc:grpc-core:jar:1.28.0:compile (version selected from constraint [1.28.0,1.28.0])
[INFO] +- io.grpc:grpc-protobuf:jar:1.28.0:compile
[INFO] | +- io.grpc:grpc-api:jar:1.28.0:compile
[INFO] | +- com.google.protobuf:protobuf-java:jar:3.11.0:compile
[INFO] | +- com.google.guava:guava:jar:28.1-android:compile
[INFO] | +- com.google.api.grpc:proto-google-common-protos:jar:1.17.0:compile
[INFO] | \- io.grpc:grpc-protobuf-lite:jar:1.28.0:compile
[INFO] +- io.grpc:grpc-stub:jar:1.28.0:compile
[INFO] +- com.google.cloud:google-cloud-firestore:jar:1.34.0:compile
[INFO] | +- com.google.cloud:google-cloud-core-grpc:jar:1.93.5:compile
...
[INFO] | +- io.grpc:grpc-context:jar:1.29.0:compile
[INFO] | +- com.google.api:gax:jar:1.56.0:compile
[INFO] | +- com.google.auth:google-auth-library-oauth2-http:jar:0.20.0:compile
[INFO] | +- com.google.errorprone:error_prone_annotations:jar:2.3.4:compile
[INFO] | +- org.codehaus.mojo:animal-sniffer-annotations:jar:1.18:compile
[INFO] | +- com.google.api:gax-grpc:jar:1.56.0:compile
[INFO] | +- io.grpc:grpc-auth:jar:1.29.0:compile
[INFO] | +- io.grpc:grpc-alts:jar:1.29.0:compile
[INFO] | +- io.grpc:grpc-grpclb:jar:1.29.0:compile
问题是 grpc-core 太旧了。你可以看到io.grpc:grpc-core:jar:1.28.0
和io.grpc:grpc-grpclb:jar:1.29.0:compile
。grpclb 依赖于 grpc-core 1.29.0。在 1.29.0 中添加了 GrpclbNameResolver,它从 grpc-core 扩展了 DnsNameResolver。但在 1.28.0 DnsNameResolver 是final
. 降级很可能导致损坏。
要修复版本问题(有几个),请将 io.grpc 依赖项移到最后,将它们的版本提升到 1.29.0。
<dependencies>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-firestore</artifactId>
<version>1.34.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-storage</artifactId>
<version>1.108.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-pubsub</artifactId>
<version>1.106.0</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-compute</artifactId>
<version>0.118.0-alpha</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-vision</artifactId>
<version>1.99.3</version>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-translate</artifactId>
<version>1.94.5</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.29.0</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.29.0</version>
</dependency>
</dependencies>
Maven 的传递依赖解析很差,并且在没有任何警告的情况下愉快地降级包。使用 maven-enforcerrequireUpperBoundDeps
检测以下问题是一种很好的做法:
<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>
由于您的依赖关系被破坏,它会注意到降级:
[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequireUpperBoundDeps failed with message:
Failed while enforcing RequireUpperBoundDeps. The error(s) are [
Require upper bound dependencies error for io.grpc:grpc-netty-shaded:1.28.0 paths to dependency are:
+-com.example:examples:1.0.0
+-io.grpc:grpc-netty-shaded:1.28.0
and
+-com.example:examples:1.0.0
+-com.google.cloud:google-cloud-firestore:1.34.0
+-io.grpc:grpc-netty-shaded:1.29.0
,
Require upper bound dependencies error for io.grpc:grpc-protobuf:1.28.0 paths to dependency are:
+-com.example:examples:1.0.0
+-io.grpc:grpc-protobuf:1.28.0
and
+-com.example:examples:1.0.0
+-com.google.cloud:google-cloud-firestore:1.34.0
+-io.grpc:grpc-protobuf:1.29.0
and
+-com.example:examples:1.0.0
+-com.google.cloud:google-cloud-pubsub:1.106.0
+-io.grpc:grpc-protobuf:1.29.0
...
推荐阅读
- flutter - Flutter中的Single-Child Layout Widget和Multi-Child Layout Widget有什么区别?
- regex - 正则表达式匹配后肺泡辅音
- mobile - 使用 FileToMemoryTable 显示的分页表
- kubernetes - Kubernetes中的CoreDNS。转发时如何附加域名?
- java - java.lang.IllegalStateException:您必须设置文本或视图
- reactjs - 以动态antd形式添加默认值
- html - iOS:删除 UIPageControl 中的填充
- apache - 使用 htacces 修改查询字符串值
- docker - 无法在 docker 中 ssh localhost
- distributed-system - raft 节点如何了解对等点?