Внедрение службы внутри TimerTask

Мне нужно ежедневно запускать процесс для выполнения работ по обслуживанию на сервере (обновления записей).

У меня есть класс Singleton scope, который запускает таймер и внутренний класс с инъекцией необходимого мне сервиса. Когда я запускаю программу, таймер выдает исключение NullPointerException, потому что служба не была введена.

@Named("demonService")
@Singleton
public class DemonImpl implements IDemonService
{
 private static Logger log = Logger.getLogger(DemonioImpl.class);

 @PostConstruct
 public void init()
 {
 log.info("-->Demon");

 Calendar today = new GregorianCalendar();//Every day at 2:00am (from now)
 today.set(Calendar.HOUR_OF_DAY, 2);
 today.set(Calendar.MINUTE, 0);
 today.set(Calendar.SECOND, 0);

 try
 {
 Timer timer = new Timer(true);
 timer.schedule(new Updater(), today.getTime(), 24*60*60*1000);
 }
 catch(Exception e)
 {
 log.fatal(e.getLocalizedMessage());
 e.printStackTrace();
 }
 log.info("--> Demon: exit");
}

private class Updater extends TimerTask
{
 private Logger log = Logger.getLogger(Updater.class);

 @Inject
 @Named("updaterService")
 private IUpdaterService updaterService;

 @Override
 public void run()
 {
 log.info("Task: update records (start)");

 List<record> list = updaterService.getAll();//<-- This throws the exception
 for(Record item : list)
 {
 updaterService.update(item);
 }

 log.info("Task: update records (exit)");
 } 
}
</record>

Ошибка

Exception in thread "Timer-3" java.lang.NullPointerException at test.service.impl.DemonImpl$Updater.run(DemonImpl.java:66) at java.util.TimerThread.mainLoop(Timer.java:555) at java.util.TimerThread.run(Timer.java:505)

Приложение отлично работает, за исключением этого класса. Как я могу ввести услугу, когда приложение полностью работает?

2 ответа

Обычно у вас есть NPE, когда класс не является биком CDI. Если вы создаете новый Updater(), это не рассматривается CDI. вы должны @Inject Updater в вашем Singleton.


CDI не будет управлять экземпляром, поскольку вы создаете экземпляр вашего Updater, вызывая его конструктор самостоятельно.

Теперь есть два способа исправить это:

  1. Внесите экземпляр класса Updater в DemonImpl и используйте его.
  2. Создайте новый управляемый экземпляр CDI во время выполнения, введя экземпляр Provider в DemonImpl и получите от него новый экземпляр класса Updater.

licensed under cc by-sa 3.0 with attribution.