@资源未设置javax.ejb.TimerService
我在尝试创建计时器时遇到NullPointerException。显然,TimerService没有设置,但我的问题是,为什么?据我所知,我正在遵循我们的应用程序中另一个类所使用的确实有效的模式 注意:我是EJB新手,所以解释很有帮助@资源未设置javax.ejb.TimerService,java,timer,ejb,Java,Timer,Ejb,我在尝试创建计时器时遇到NullPointerException。显然,TimerService没有设置,但我的问题是,为什么?据我所知,我正在遵循我们的应用程序中另一个类所使用的确实有效的模式 注意:我是EJB新手,所以解释很有帮助 @Stateless public class MyClass implements SomeInterface { private static final Logger ourLogger = new Logger(MyClass.class);
@Stateless
public class MyClass implements SomeInterface
{
private static final Logger ourLogger = new Logger(MyClass.class);
private volatile Timer timer = null;
private volatile static MyClass instance = null;
@javax.annotation.Resource
TimerService timerService;
@Override
public synchronized void myMethod()
{
resetTimer();
//do other stuff
}
/**
* Creates the timer.
*/
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
private synchronized void resetTimer()
{
if (timer != null)
{
timer.cancel();
timer = null;
}
//NullPointerException on next line:
timer = timerService.createTimer(30000, "My Note");
}
public static MyClass getInstance()
{//MDB calls this, then runs instance.myMethod
if (instance == null)
{
instance = new MyClass ();
}
return instance;
}
@Timeout
public synchronized void timeout()
{
//Do some stuff
instance = null;
}
}
您发布的其他代码在错误代码列表中又添加了一项内容(我从您问题的第一条注释开始) 您正在尝试在SLSB中实现单例设计模式。这在很多方面都是错误的 如果您需要单例-只需使用
@singleton
EJB即可。如果您按照发布的方式进行操作,那么您基本上不是在实例化EJB,而是在实例化一些常规Java类。难怪注入没有发生——容器对您在方法中创建的实例一无所知
如果您想要一个EJB,只需给它一个默认构造函数,并从MDB使用它和@EJB
。然后容器将对其进行实例化,并赋予其EJB特性(包括所有这些管理生命周期、池、依赖注入等)
综上所述,您可以在发布的代码中找到错误内容的列表:
- 您在一个无状态的EJB中持有一个状态
- 您正在将一个单例模式实现到由规范汇集的EJB中
- 您已经在进行线程安全的同步(也按规范)EJB
- 您正在将
添加到私有方法;我甚至不确定这是否有意义@TransactionAttribute
表示您正在定义业务方法。同时,这个方法是私有的,这意味着它不能成为业务接口的一部分,所以它不是一个业务方法@TransactionAttribute
希望这对你有帮助 在Oracle的Java EE 6教程中: 要保存计时器对象以供将来引用,请调用其getHandle方法并将TimerHandle对象存储在数据库中
如果您想省去这项不愉快的工作,另一种方法是向
@Stateless
bean中注入一个单例bean,将计时器实例存储到@Singleton
bean的属性中,并在Singleton bean中运行/取消计时器。您是否有TimerService
的ejb声明?尽管injection-1存在整个问题。为什么在无状态EJB中保存状态(存储计时器)?2.为什么要同步线程安全EJB?最后,你为什么把私有方法当作一种商业方法?您如何调用这个bean并知道TimerService
没有设置呢?@SotiriosDelimanolis我们有另一个类遵循这个模式,在同一个模式中注入TimerServicemanner@PiotrNowicki我是从MessageDrivenBean打电话来的。这只是课程的一部分。我存储计时器,以便可以取消和重置计时器。resetTimer()方法是从另一个为简洁起见未显示的方法运行的。我问您如何调用此bean的原因是,您可能不将其用作EJB,而是将其用作常规类,因此不会注入TimerService
。这是第一部分。第二,如果你在SLSB中存储了任何东西,你不能确定下次它会处于你离开它时的状态,因此你真的不应该这样做。你说的有道理,但现在我已经将它改为@Singleton
,并在我的MDB中添加了@EJB
字段,我的MDB不再接收消息。没有例外,只是当我发送JMS消息时什么都没有发生。我可能会遇到什么“怪癖”?嗯,从这么短的描述很难说。您可以显示更多的代码(特别是MDB和与新的单例bean的交互),或者测试它是否与@EJB
一起工作,以及它的使用是否在MDB中被注释并启用。这是唯一改变的吗?请参见编辑注释下的代码。也许应该让它成为一个新问题,但既然你已经熟悉它了……再想想,这应该是一个新问题。我已将编辑移到此链接: