如何正确使用Java EE的@Startup?
我想将 Java EE 应用程序中长时间运行的进程从同步执行转移到异步执行。该过程应自动启动,然后每小时运行一次。 该项目在 Glassfish 3.1 和 Java EE 6 中运行。
经过一些阅读,我相信我可以通过 @Singleton
和 @Startup
在 Java EE 6 中启动此类服务。 因此,我创建一个新类
@Startup
@Singleton
public class MyService {
}
并通过 Maven 运行现有的集成测试。 令我惊讶的是,测试失败了,连最基本的“页面在那里”测试都失败了。他们不再找到网页,而是收到错误页面。
在实验中,我删除了 @Startup
注释,并再次运行测试。这一次,他们成功了。
手动启动服务器并导航到该页面会产生预期结果:该页面就在那里。 更重要的是,在 Eclipse 中,他们在两个注释都到位的情况下成功进行了测试。我能看到的唯一区别是,启动服务器的是 eclipse,而不是 Cargo Maven 插件。
这里可能会出现什么问题? 我需要做什么才能正确使用@Startup
?
更新: 从eclipse切换回IntelliJ IDEA后,我仍然遇到这个问题。 然而,我看到了一些例外——也许你可以从中做点什么:
[#|2011-07-25T10:22:51.529+0200|严重|glassfish3.1|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=65;_ThreadName=Thread- 1;|调用类 org.glassfish.ejb.startup.EjbApplication start 时出现异常方法
javax.ejb.EJBException:javax.ejb.CreateException:单例邮件服务初始化失败 在 com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:719) 在com.sun.ejb.containers.AbstractSingletonContainer.instantiateSingletonInstance(AbstractSingletonContainer.java:449) 在 org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:216) 在 org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:177) 在 org.glassfish.ejb.startup.SingletonLifeCycleManager.doStartup(SingletonLifeCycleManager.java:155) 在 org.glassfish.ejb.startup.EjbApplication.start(EjbApplication.java:177) ...
原因:javax.ejb.CreateException:Singleton MailService 初始化失败 在 com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:545) 在 com.sun.ejb.containers.AbstractSingletonContainer.access 100 美元(AbstractSingletonContainer.java:79) 在 com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:717) ... 36 更多
引起:java.lang.NullPointerException 在 java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768) 在 org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:1209) 在 org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:144) 在 org.glassfish.weld.services.JCDIServiceImpl._createJCDIInjectionContext(JCDIServiceImpl.java:144)
I want to move a long-running process in an Java EE application from synchronous to asynchronous execution. The process should start automatically and then run every hour.
The project runs in Glassfish 3.1 with Java EE 6.
After some reading, I believe that I can start such services in Java EE 6 via @Singleton
and @Startup
.
So, I create a new class
@Startup
@Singleton
public class MyService {
}
and run the existing integration tests via maven.
To my surprise, the tests fail, down to the the most basic "page is there"-test. They don't find the webpages any longer, instead getting error pages.
Experimenting, I remove the @Startup
annotation, and run the tests once more. This time, they succeed.
Manually starting a server and navigating to the page yields the expected result: The page is there.
What's more, in eclipse, the tests they succeed with both annotations in place. The only difference I can see is that it is eclipse that starts the server, not the Cargo Maven plugin.
What could possibly go wrong here?
What do I have to do to use @Startup
correctly?
Update:
After switching back to IntelliJ IDEA from eclipse, I still have this problem.
However, I see some exceptions - maybe you can make something out of them:
[#|2011-07-25T10:22:51.529+0200|SEVERE|glassfish3.1|javax.enterprise.system.tools.deployment.org.glassfish.deployment.common|_ThreadID=65;_ThreadName=Thread-1;|Exception while invoking class org.glassfish.ejb.startup.EjbApplication start method
javax.ejb.EJBException: javax.ejb.CreateException: Initialization failed for Singleton MailService
at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:719)
at com.sun.ejb.containers.AbstractSingletonContainer.instantiateSingletonInstance(AbstractSingletonContainer.java:449)
at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:216)
at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:177)
at org.glassfish.ejb.startup.SingletonLifeCycleManager.doStartup(SingletonLifeCycleManager.java:155)
at org.glassfish.ejb.startup.EjbApplication.start(EjbApplication.java:177)
...Caused by: javax.ejb.CreateException: Initialization failed for Singleton MailService
at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:545)
at com.sun.ejb.containers.AbstractSingletonContainer.access$100(AbstractSingletonContainer.java:79)
at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:717)
... 36 moreCaused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:768)
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:1209)
at org.jboss.weld.manager.BeanManagerImpl.getBean(BeanManagerImpl.java:144)
at org.glassfish.weld.services.JCDIServiceImpl._createJCDIInjectionContext(JCDIServiceImpl.java:144)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
毕竟问题不在于注释,而在于放错位置的
beans.xml
。根据需要将其放入META-INF
中,帮助我解决了这一问题。切换到 IntelliJ IDEA 有助于解决问题:日志文件中包含将 bean 创建为
@Singleton
以及@ApplicationScoped
时出现的高度可见的错误。另一件被证明非常有帮助的事情是在 JBoss 中尝试完全相同的应用程序。在这里,它起作用了,所以我确信我没有误解基本概念。
The problem wasn't with the annotations after all, it was a misplaced
beans.xml
. Putting it inMETA-INF
, as required, helped me to get past this one.Switching to IntelliJ IDEA helped solve the problem: In it, the log file contained highly visible errors for creating the bean as a
@Singleton
as well as a@ApplicationScoped
.Another thing that proved very helpful was to try the exact same application in JBoss. Here, it worked, so I was confident I had not misunderstood the basic concepts.