我正在编写一个在 GlassFish 2.1.1 上运行的 Web 应用程序。该应用程序实际上只包含一个无状态 session bean,它使用第三方库中的类。此类的实例是在运行时创建大量自管理线程的服务。我在 EJB 限制中读到,在 EJB 中创建线程不是一个好主意。
我对 Java EE 和 EJB 还很陌生,但我想知道如何在 EJB 环境中使用不是为 EJB 开发的第三方库。我想知道如何使用 EJB 以保存的方式在我的 Java EE 应用程序中嵌入这个第三方服务,它是一个简单的单例。
我唯一的想法是在 servlet 中实例化服务并通过方法调用将实例传递给 EJB。这是更好的方法吗?
提前致谢 亚历克斯
有关我的项目的更多详细信息:
我必须使用的库肯定不是为 EJB 容器设计的。然而,我别无选择。我也改变了我的设计,我尝试简要解释一下。 我的网络应用程序的主要目的是处理作业。基本上它类似于 CI 服务器 hudson。工作是其他东西,然后是构建任务。但是,可以通过 Web GUI 启 Action 业。如果用户按下开始按钮,则仅将具有状态的条目插入到数据库表中。数据库表用作执行队列。另一个 bean,TimerBean 将定期检查数据库并调用 enginge(我的第三方库)来处理此作业。作业处理与客户端解耦,不需要事务。
- 它会在方法调用之间保留状态吗? 是的,我必须保留当前作业才能取消执行。我已经用静态变量解决了这个问题。我知道这也是我不应该在 EJB 中做的事情,但 EJB 永远不会用于集群。
- 它是否访问文件、打开连接? 第三方库读写文件。
- 它是否使用共享资源(例如类)来同步线程 变量?我不知道第三方库的内部结构,但我想,是的!
最佳答案
The instances of this classes are services which create a lot of self managed threads during the runtime
看到这一点,你的脑海中应该会亮起一个红色的大警报灯。这仅表明您的库可能不适合与 EJB 一起使用,并且在继续集成之前您应该彻底了解它的工作原理。
您可能想问的其他一些问题:
- 它会在方法调用之间保留状态吗?
- 它是否访问文件、打开连接?
- 它是否使用共享资源(例如类变量)来同步线程?
由于您的库可能会尝试根据环境进行扩展,因此一个预防措施可能是确保通过单例 EJB 访问它(这至少会增加在单个 VM 上正确运行的机会)。要在 GF 2.1 上实现此目的,您需要在 sun-ejb-jar.xml
中进行设置:
<ejb>
<ejb-name>MyEJB</ejb-name>
<jndi-name>ejb/MyEJB</jndi-name>
<bean-pool>
<steady-pool-size>1</steady-pool-size>
<max-pool-size>1</max-pool-size>
</bean-pool>
</ejb>
您可以在 MyEJB
的 @PostConstruct
方法中初始化您的库,无需使用特殊的 servlet。
这只是解决方案的一个草图,一切都取决于库的实际工作方式。
关于java - 如何在使用 EJB3 的 Java EE 环境中嵌入第三方代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9130444/