HBase client 1.x with gRPC

Imagine, that you need to use the HBase client 1.x and gRPC in the same Java application. The code for connecting dependencies to Maven will look something like this:

<!-- HBase -->
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-client</artifactId>
  <version>1.2.3</version>
</dependency>
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-common</artifactId>
  <version>1.2.3</version>
</dependency>

<!-- gRPC -->
<dependency>
  
  <groupId>io.grpc</groupId>
  
  <artifactId>grpc-netty</artifactId>
  
  <version>1.16.1</version>

</dependency>

<dependency>
 
  <groupId>io.grpc</groupId>
  
  <artifactId>grpc-protobuf</artifactId>
  
  <version>1.16.1</version>

</dependency>
<dependency>
 
  <groupId>io.grpc</groupId>
 
  <artifactId>grpc-stub</artifactId>
  
  <version>1.16.1</version>

</dependency>

If you run the application and execute the request through the HBase client, there will be an exception:

java.lang.IllegalAccessError: tried to access method com.google.common.base.Stopwatch.<init>()V from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator
        at org.apache.hadoop.hbase.zookeeper.MetaTableLocator.blockUntilAvailable(MetaTableLocator.java:601) ...

The problem is that hbase-client 1.x uses an earlier version of Google Protobuf – 2.5.0, than gRPC. Sometimes the problem appears because Guava version difference.  

You can try two different solutions.

Use hbase-shaded-client 1.x

<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-shaded-client</artifactId>
  <version>1.2.3/version>
</dependency>
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-common</artifactId>
  <version>1.2.3</version>
</dependency>

Use hbase-client 2.x

Starting with the HBase client version 2.0.0, the shaded Protobuf classes appeared there, so there is no conflict. You need to update the HBase client version to 2.0.0:

<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-client</artifactId>
  <version>2.0.0</version>
</dependency>
<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-common</artifactId>
  <version>2.0.0</version>
</dependency>

But do this very carefully, because hbase-client 2.x s NOT fully compatible with hbase-server 1.x. For example, the Admin API is going to broke. Sometimes you can face with unclear errors under the heavy load. So you need to test it very precisely.

If you still have any questions, feel free to ask me in the comments under this article, or write me on promark33@gmail.com.

Leave a Reply

Your email address will not be published.