javamavengrpcgrpc-javatikv

Java-grpc and tikv-java: NoSuchFieldError: CONTEXT_SPAN_KEY


I am using java-grpc together with tikv-java (separately they work OK). But together I am struggling with the following error:

Exception in thread "main" java.lang.NoSuchFieldError: CONTEXT_SPAN_KEY
        at io.grpc.internal.CensusTracingModule$TracingClientInterceptor.interceptCall(CensusTracingModule.java:327)
        at io.grpc.ClientInterceptors$InterceptorChannel.newCall(ClientInterceptors.java:104)
        at io.grpc.internal.ManagedChannelImpl.newCall(ManagedChannelImpl.java:551)
        at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:113)
        at com.pv.app.GetInsertServiceGrpc$GetInsertServiceBlockingStub.insert(GetInsertServiceGrpc.java:195)
        at com.pv.app.Client.main(Client.java:55)

My code-client:

package com.pv.app;

import io.grpc.*;

public class Client {
  public static void main(String[] args) throws Exception {
    // Channel is the abstraction to connect to a service endpoint
    // Let's use plaintext communication because we don't have certs
    final ManagedChannel channel =
        ManagedChannelBuilder.forTarget("0.0.0.0:8080").usePlaintext().build();


    GetInsertServiceGrpc.GetInsertServiceBlockingStub stub =
        GetInsertServiceGrpc.newBlockingStub(channel);
    GetInsertServiceOuterClass.HelloMessage request =
        GetInsertServiceOuterClass.HelloMessage.newBuilder().setName("hello").build();

    System.out.println(request);

    System.out.println("b4 req");

    // Finally, make the call using the stub
    stub.insert(request);

    channel.shutdownNow();
  }
}


My code-server:

package com.pv.app;

import io.grpc.Server;
import io.grpc.ServerBuilder;



/** Hello world! */
public class App {
  public static void main(String[] args) throws Exception {

    System.out.println("Hello-start");
    Server server = ServerBuilder.forPort(8080).addService(new GetInsertServiceImpl()).build();

    // Start the server
    server.start();

    // Server threads are running in the background.
    System.out.println("Server started");
    // Don't exit the main thread. Wait until server is terminated.
    server.awaitTermination();

  }
}

My code-implementation:

package com.pv.app;


import org.tikv.common.TiConfiguration;
import org.tikv.common.TiSession;
import org.tikv.raw.RawKVClient;

public class GetInsertServiceImpl
    extends GetInsertServiceGrpc.GetInsertServiceImplBase {

  @Override
  public void insert(
      GetInsertServiceOuterClass.HelloMessage request,
      io.grpc.stub.StreamObserver<com.google.protobuf.Empty> responseObserver) {
    // HelloRequest has toString auto-generated.
    System.out.println("insert");
    System.out.println(request);
    TiConfiguration conf = TiConfiguration.createRawDefault("pd0:2379");
    System.out.println(1);
    System.out.println("2");
    System.out.println(conf);
    TiSession session = TiSession.create(conf);
    System.out.println("3");
    RawKVClient client = session.createRawClient();
    System.out.println("4");



    // When you are done, you must call onCompleted.
    responseObserver.onCompleted();
  }
}

My proto:

syntax = "proto3";
import "google/protobuf/empty.proto";


option java_package = "com.pv.app";
// Request payload


message HelloMessage {

    string name = 1;

}

// Defining a Service, a Service can have multiple RPC operations
service GetInsertService {
    // Define a RPC operation
    rpc insert (HelloMessage) returns (google.protobuf.Empty) {
    };

}

What I do to deploy:

mvn install:install-file \
-Dfile=../client-java/target/tikv-client-java-2.0-SNAPSHOT.jar  \
-DgroupId=org.tikv \
-DartifactId=tikv-client-java \
-Dversion=2.0-SNAPSHOT \
-Dpackaging=jar
<dependency>
  <groupId>org.tikv</groupId>
  <artifactId>tikv-client-java</artifactId>
  <version>2.0-SNAPSHOT</version>
</dependency>
mvn -DskipTests package exec:java -Dexec.mainClass=com.pv.app.App  
mvn -DskipTests package exec:java -Dexec.mainClass=com.pv.app.Client 

Does anyone have a suggestion how to fix?

Full code is available here

I did my searching, tried to exclude grpc and opencensus, switch versions - did not help.


Solution

  • The problem is caused by conflicting io.opencensus versions. I was able to fix it by shading it in the tikv/client-java project.

    In the tikv/client-java, pom.xml, maven-shade-plugin configuration:

    <relocations>
        ...
        <relocation>
            <pattern>io.opencensus</pattern>
            <shadedPattern>shade.io.opencensus</shadedPattern>
        </relocation>
    <relocations>
    

    UPDATE

    I have just realized that there were changes to the pom.xml merged to the master yesterday, so you may want to update it if you haven't yet.

    UPDATE 2

    I have just checked your project with the recent version of the tikv/client-java. The NoSuchFieldError: CONTEXT_SPAN_KEY is gone. There are other errors (java.net.UnknownHostException) but they are rather not related.