You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

gRPC BlockingStub空指针异常求助:客户端调用失败

gRPC客户端BlockingStub空指针问题排查与解决

问题现象

客户端调用gRPC服务时触发NullPointerException,报错核心信息:

java.lang.NullPointerException: Cannot invoke "com.ky.BookServiceGrpc$BookServiceBlockingStub.getBookIdByIsbn(com.ky.Isbn)" because "this.bookServiceStub" is null

核心原因

1. 服务类未被Spring容器托管

LibraryService类没有添加@Service(或@Component)注解,导致Spring无法识别该类,也就不会处理@GrpcClient注解,最终bookServiceStub字段无法被注入,始终为null。

2. 辅助排查点

  • 确认@GrpcClient("book-service")中的服务名称与配置文件中gRPC客户端的服务名称完全一致,确保服务发现/配置匹配
  • 检查生成的stub包路径一致性:生成的BookServiceBlockingStub中引用的是com.ky.common.proto.BookIsbn,但业务代码中使用的是com.ky.BookIsbn,虽当前报错是空指针,但后续可能引发类型转换问题,需保证proto生成的类路径统一

解决方案

方案一:让Spring托管LibraryService(推荐)

给LibraryService添加@Service注解,确保Spring能够扫描并管理该类,自动处理@GrpcClient的注入逻辑:

import org.springframework.stereotype.Service;

@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);
    }
}

方案二:手动创建Stub实例(无Spring注解场景)

如果不想依赖Spring的注解注入,可以手动通过gRPC通道构建Stub:

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class LibraryService {
    private final BookServiceGrpc.BookServiceBlockingStub bookServiceStub;
    private final LibraryRepository libraryRepository;
    private final BookServiceClient bookServiceClient;
    private final UserServiceClient userServiceClient;
    private final LibraryMapper libraryMapper;

    public LibraryService(LibraryRepository libraryRepository, BookServiceClient bookServiceClient, UserServiceClient userServiceClient, LibraryMapper libraryMapper) {
        // 手动创建通道和Stub,替换为实际服务地址与端口
        ManagedChannel channel = ManagedChannelBuilder.forAddress("book-service-host", 9090)
                .usePlaintext() // 根据实际配置选择是否启用TLS
                .build();
        this.bookServiceStub = BookServiceGrpc.newBlockingStub(channel);
        
        // 初始化其他依赖
        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);
    }
}

额外注意事项

  • 确保net.devh:grpc-spring-boot-starter依赖已正确引入,版本与Spring Boot版本兼容
  • 若使用服务发现,确认book-service能被客户端正常发现(如Nacos、Eureka等配置正确)

内容的提问来源于stack exchange,提问作者kaanyvz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:48:11