Quarkus使用jboss Logger输出日志报NullPointerException问题咨询
问题根因
报错栈已经明确给出异常原因:java.lang.NullPointerException: Cannot invoke "org.jboss.logging.Logger.info(Object)" because "this.log" is null,即代码中声明的log对象未初始化,值为null,调用info方法时触发空指针。
当前代码仅写了Logger log;,既没有手动初始化日志实例,也没有添加注解让CDI容器为该字段注入实例,运行时对象字段默认值为null,调用方法必然报错。
此外代码中还存在一个CDI使用的典型错误:直接通过new FindPrepaidSubscriberICCIDRepository()手动实例化Repository对象,这种方式创建的对象不受Quarkus Arc容器管理,后续如果Repository内部有@Inject标记的依赖,所有依赖都会是null,会触发新的空指针异常。
贴出的application.properties日志配置、pom.xml依赖配置都没有问题,本次异常和配置、依赖无关。
修复方法
1. 正确初始化Logger实例
Quarkus中使用JBoss Logger有两种标准实现方式,推荐第一种:
- 静态初始化(无注入依赖,性能最优,最常用)
将原有Logger log;替换为以下代码:
private static final Logger log = Logger.getLogger(FindPrepaidSubscriberICCID.class);
- CDI容器注入
如果需要走容器注入,给log字段添加@Inject注解即可:
@Inject Logger log;
2. 修正Repository的实例化方式
不要手动new Repository实例,首先给FindPrepaidSubscriberICCIDRepository类添加CDI Bean注解(例如@ApplicationScoped、@Singleton,根据业务需求选择),然后将原有手动new的代码替换为容器注入:
@Inject FindPrepaidSubscriberICCIDRepository repository;
修复后核心代码参考
package com.tmve.subscriber; import com.tmve.subscriber.repository.FindPrepaidSubscriberICCIDRepository; import io.agroal.api.AgroalDataSource; import org.jboss.logging.Logger; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import java.util.HashMap; @Path("/api") public class FindPrepaidSubscriberICCID { // 静态初始化日志实例 private static final Logger log = Logger.getLogger(FindPrepaidSubscriberICCID.class); @Inject AgroalDataSource defaultDataSource; // 容器注入Repository,禁止手动new @Inject FindPrepaidSubscriberICCIDRepository repository; private final String movil = "142910399"; @GET @Produces(MediaType.TEXT_PLAIN) public HashMap<String,String> hello() { HashMap<String,String> map = repository.getResources(defaultDataSource, movil); log.info("movil: " + movil); return map; } }

内容的提问来源于stack exchange,提问作者Cesar Justo
相关产品推荐
相关产品推荐

