无法从 Spring Boot 应用程序连接到 Bigtable

Posted

技术标签:

【中文标题】无法从 Spring Boot 应用程序连接到 Bigtable【英文标题】:Can't connect to Bigtable from a Spring Boot application 【发布时间】:2017-01-23 17:55:37 【问题描述】:

我有一个独立的应用程序,在创建这样的连接时可以很好地与 Bigtable 配合使用:

Connection connection = BigtableConfiguration.connect(PROJECT_ID, INSTANCE_ID)

并使用以下依赖项:

<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-storage</artifactId>
    <version>v1-rev78-1.22.0</version>
</dependency>
<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-pubsub</artifactId>
    <version>v1-rev11-1.22.0</version>
</dependency>
<dependency>
    <groupId>com.google.cloud.bigtable</groupId>
    <artifactId>bigtable-hbase-1.2</artifactId>
    <version>0.9.5</version>
</dependency>
<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>1.2.4</version>
</dependency>
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-tcnative-boringssl-static</artifactId>
    <version>1.1.33.Fork26</version>
</dependency>

我现在将其转换为 Spring Boot Web 应用程序,因此我必须添加此依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>1.4.2.RELEASE</version>
</dependency>

我根本没有更改任何其他内容,只是添加了这 5 行,现在我收到了这个错误:

java.lang.IllegalStateException: Could not find an appropriate constructor for com.google.cloud.bigtable.hbase1_1.BigtableConnection
    at com.google.cloud.bigtable.hbase.BigtableConfiguration.connect(BigtableConfiguration.java:88)
    at com.google.cloud.bigtable.hbase.BigtableConfiguration.connect(BigtableConfiguration.java:72)
    at poc.google.cloud.BigtableTest.testHelloWorld(BigtableTest.java:57)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at com.google.cloud.bigtable.hbase.BigtableConfiguration.connect(BigtableConfiguration.java:85)
    ... 28 more
Caused by: java.lang.IllegalStateException: Neither Jetty ALPN nor OpenSSL via netty-tcnative were properly configured.
    at com.google.cloud.bigtable.grpc.BigtableSession.<init>(BigtableSession.java:258)
    at org.apache.hadoop.hbase.client.AbstractBigtableConnection.<init>(AbstractBigtableConnection.java:137)
    at org.apache.hadoop.hbase.client.AbstractBigtableConnection.<init>(AbstractBigtableConnection.java:104)
    at com.google.cloud.bigtable.hbase1_1.BigtableConnection.<init>(BigtableConnection.java:48)
    ... 33 more

【问题讨论】:

我不认为我曾经测试过 tcnative Fork26 并且对 Fork19 很幸运;我不知道是不是这个问题。我遇到了各种与 tcnative 相关的类路径,这些类路径源自码头和 tomcat 环境的排序问题,例如:github.com/GoogleCloudPlatform/cloud-bigtable-client/issues/876 和***.com/questions/39421958/…。我无法调试问题 我试过1.1.33.Fork19,但没有成功。现在我知道它与spring-boot-starter-web带来的org.apache.tomcat.embed:spring-boot-starter-tomcat传递依赖有关 tcnative 中的 'tc' 代表 tomcat。当 tcnative 和 tomcat 都可用时,存在某种冲突。一种可能的替代方法是使用 alpn_boot,尽管 gRPC 强烈建议不要这样做...github.com/grpc/grpc-java/blob/master/… 我找到了一个简单的解决方法,如我的回答中所述,以防它在 Bigtable Java 客户端库的未来开发中帮助您。非常感谢 【参考方案1】:

用于连接 Bigtable 的库似乎与 Spring Boot 默认使用的 Tomcat 库存在某种冲突。

使用 Jetty 而不是 Tomcat 作为解决方法。

com.google.protobuf:protobuf-java 在此转换后丢失了,所以不要忘记添加它

这是在 Spring Boot 中用 Tomcat 替换 Jetty 的方法:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
<!-- Excluding spring-boot-starter-tomcat from Spring Boot and adding spring-boot-starter-jetty
made protobuf-java disappear although it's still needed -->
<dependency>
    <groupId>com.google.protobuf</groupId>
    <artifactId>protobuf-java</artifactId>
    <version>3.1.0</version>
</dependency>

【讨论】:

以上是关于无法从 Spring Boot 应用程序连接到 Bigtable的主要内容,如果未能解决你的问题,请参考以下文章

无法从 docker 容器内的 Spring Boot 连接到 Redis

当我将 Spring Boot 应用程序部署到 AWS Elastic Beanstalk 并且无法从本地 Spring Boot 连接到 RDS 时出现 502 错误网关

无法从 Spring Boot Docker 容器连接到本地 MySQL 数据库服务器

无法从通过intellij运行的spring boot应用程序连接到我在docker上运行的kafka

无法从Spring Boot Docker容器连接到本地MySQL数据库服务器

无法使用 Spring Boot 应用程序连接到 Docker 映像