grpc BlockingStub returns null
Asked Answered
U

1

6

i am trying to use grpc in my project but i have a problem, my problem is at grpc client side i want to use blockingStub however, it turns NullPointerException. here is my classes:

common-service Book.proto:

syntax = "proto3";
option java_multiple_files = true;
package com.ky;

service BookService {
  rpc getBookIdByIsbn(Isbn) returns (BookIsbn);
}

message BookIsbn {
  string bookId = 1;
  string isbn = 2;
  int32 stockCount = 3;
}

message Isbn{
  string isbn = 1;
}

Book-service bookServiceGrpcImpl:

package com.ky.bookservice.service;
import com.ky.BookIsbn;
import com.ky.BookServiceGrpc;
import com.ky.Isbn;
import com.ky.bookservice.dto.book.BookIsbnDto;
import com.ky.bookservice.dto.book.BookMapper;
import com.ky.bookservice.repository.BookRepository;

import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@GrpcService
public class BookGrpcServiceImpl extends BookServiceGrpc.BookServiceImplBase {
    private static final Logger logger = LoggerFactory.getLogger(BookGrpcServiceImpl.class);
    private final BookRepository bookRepository;
    private final BookMapper bookMapper;

    public BookGrpcServiceImpl(BookRepository bookRepository, BookMapper bookMapper) {
        this.bookRepository = bookRepository;
        this.bookMapper = bookMapper;
    }

    @Override
    public void getBookIdByIsbn(Isbn request, StreamObserver<BookIsbn> responseObserver) {
        logger.info("Grpc Call Received: " + request.getIsbn());
        BookIsbnDto bookIsbnDto = bookRepository
                .findBookByIsbn(request.getIsbn())
                .map(bookMapper::bookToBookIsbnDto)
                .orElseThrow(() -> new RuntimeException("Book could not found by isbn: " + request.getIsbn()));
        responseObserver.onNext(
                BookIsbn.newBuilder()
                        .setBookId(bookIsbnDto.getId().toString())
                        .setIsbn(bookIsbnDto.getIsbn())
                        .setStockCount(bookIsbnDto.getStockCount())
                        .build()
        );
        responseObserver.onCompleted();
    }
}

library-service:

public class LibraryService {
    private final LibraryRepository libraryRepository;
    private final BookServiceClient bookServiceClient;
    private final UserServiceClient userServiceClient;
    private final LibraryMapper libraryMapper;

    @GrpcClient("book-service")
    private BookServiceGrpc.BookServiceBlockingStub bookServiceStub;

    Logger logger = LoggerFactory.getLogger(LibraryService.class);

    public LibraryService(LibraryRepository libraryRepository, BookServiceClient bookServiceClient, UserServiceClient userServiceClient, LibraryMapper libraryMapper) {
        this.libraryRepository = libraryRepository;
        this.bookServiceClient = bookServiceClient;
        this.userServiceClient = userServiceClient;
        this.libraryMapper = libraryMapper;
    }

    public void addBookToLibrary(AddBookRequest addBookRequest){
        BookIsbn bookId = bookServiceStub.getBookIdByIsbn(Isbn.newBuilder().setIsbn(addBookRequest.getIsbn()).build());
        

        Library library = libraryRepository.findById(addBookRequest.getId())
                .orElseThrow(() -> new LibraryNotFoundException("Library could not found by id: " + addBookRequest.getId()));

        library.getUserBook().add(UUID.fromString(bookId.getBookId()));

        libraryRepository.save(library);
    }
}

generated BookServiceBlockingStub class:

public static final class BookServiceBlockingStub extends io.grpc.stub.AbstractStub<BookServiceBlockingStub> {
    private BookServiceBlockingStub(io.grpc.Channel channel) {
      super(channel);
    }

    private BookServiceBlockingStub(io.grpc.Channel channel,
        io.grpc.CallOptions callOptions) {
      super(channel, callOptions);
    }

    @java.lang.Override
    protected BookServiceBlockingStub build(io.grpc.Channel channel,
        io.grpc.CallOptions callOptions) {
      return new BookServiceBlockingStub(channel, callOptions);
    }

    /**
     */
    public com.ky.common.proto.BookIsbn getBookIdByIsbn(com.ky.common.proto.Isbn request) {
      return blockingUnaryCall(
          getChannel(), METHOD_GET_BOOK_ID_BY_ISBN, getCallOptions(), request);
    }
  }

when i try to use addBookToLibrary method i gave an error like that what's the problem. Thanks:

java.lang.NullPointerException: Cannot invoke "com.ky.BookServiceGrpc$BookServiceBlockingStub.getBookIdByIsbn(com.ky.Isbn)" because "this.bookServiceStub" is null
    at com.ky.libraryservice.service.LibraryService.addBookToLibrary(LibraryService.java:97) ~[classes/:na]
    at com.ky.libraryservice.controller.LibraryController.addBookToLibrary(LibraryController.java:29) ~[classes/:na]
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:578) ~[na:na]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-6.0.11.jar:6.0.11]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:925) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:593) ~[tomcat-embed-core-10.1.12.jar:6.0]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.11.jar:6.0.11]
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.12.jar:6.0]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.11.jar:6.0.11]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.11.jar:6.0.11]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.11.jar:6.0.11]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.11.jar:6.0.11]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.11.jar:6.0.11]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.11.jar:6.0.11]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.12.jar:10.1.12]
    at java.base/java.lang.Thread.run(Thread.java:1589) ~[na:na]
Unhurried answered 4/9, 2023 at 15:1 Comment(0)
L
0

You have to use the client in spring context / IOC container (springboot or other stack).

So LibraryService must be annotate with @Service to inject @GrpcClient("book-service").

@Service    
public class LibraryService {

You need also a factory like that :

@Configuration
@GrpcClientBean(
    clazz = BookServiceGrpc.BookServiceBlockingStub.class,
    beanName = "bookServiceStub",
    client = @GrpcClient("book-service")
)
public class LibraryCustomConfiguration {

    @Bean
    LibraryService libraryService (@Autowired BookServiceGrpc.BookServiceBlockingStub bookServiceStub...) {
        return new LibraryService (blockingStub....);
    }

}
Logogriph answered 5/9, 2023 at 7:19 Comment(4)
thanks for your reply however, it's still same. Still returns null. I don't understand what's wrong.Unhurried
it's still poor. I added generated class also.Unhurried
I'm getting the same error. Did anyone find a solution?Battleship
Got it. We have a custom AutoConfigurationFilter that filtered the Grpc AutoConfiguration classes out. Therefore, no GrpcClients have been created. After disabling that custom AutoConfigurationFilter, it worked as expected.Battleship

© 2022 - 2024 — McMap. All rights reserved.