[英]Run-time lookup for EJBs in MDB consuming immediately after deploy
I have Java EE 5 project using JBoss 5.1 and problem like this. 我有使用JBoss 5.1的Java EE 5项目和这样的问题。 I have to do kind of run-time lookup for some EJBs in MDBs using a string that results from message content.
我必须使用由消息内容产生的字符串对MDB中的某些EJB执行某种运行时查找。 It's just kind of service locator pattern used in MDBs.
它只是MDB中使用的一种服务定位器模式。 Now, since MDBs start consuming just after deploy, I have a lot
NameNotFoundException
since implicit deployment order doesn't work well here (run-time lookup). 现在,由于MDB在部署之后就开始消耗,因此我有很多
NameNotFoundException
因为隐式部署顺序在这里不能正常工作(运行时查找)。 What do you think about it? 你怎么看待这件事? Is it possible to do it really well using EJB 3.0?
是否有可能使用EJB 3.0做得很好? It's also acceptable for me to use any vendor-specific stuff (JBoss 5.1) if it resolves the problem.
如果解决问题,我也可以使用任何特定于供应商的东西(JBoss 5.1)。
Some code snippet to visualize the situation: 一些代码片段可视化情况:
@MessageDriven(mappedName="jms/Queue")
public class MessageBean implements MessageListener {
@Resource
private MessageDrivenContext mdc;
public void onMessage(Message msg) {
final String beanName = // extract somehow the bean's name from 'msg'
final Context ctx = new InitialContext();
final Object obj = ctx.lookup(beanName); // NameNotFoundException
// do something with 'obj'
}
}
Use one of these four different approaches. 使用这四种不同方法中的一种。
Declare EJB dependencies ( EJB references ) using "@EJB" annotation (don't use JNDI lookup). 使用“@EJB”注释声明EJB依赖项( EJB引用 )(不要使用JNDI查找)。 For entity bean references, must refer to the entity bean home interface.
对于实体bean引用,必须引用实体bean home接口。 Container must ensure all dependencies are injected before methods/message-listeners are processed:
容器必须确保在处理方法/消息侦听器之前注入所有依赖项:
MessageDriven(mappedName="jms/Queue") 消息驱动(mappedName = “JMS /队列”)
public class MessageBean implements MessageListener { 公共类MessageBean实现MessageListener {
@EJB private EntityBeanHomeA entityBeanHomeA; @EJB private EntityBeanHomeB entityBeanHomeB; @EJB private EntityBeanHomeC entityBeanHomeC; @EJB private SessionBeanD sessionBeanD; @Resource private MessageDrivenContext mdc; public void onMessage(Message msg) { final String beanName = // extract somehow the bean's name from 'msg' final Object obj = getDependentEJB(beanName); // do something with 'obj' } private Object getDependentEJB(String beanName) { Object result = null; if ("EntityBeanHomeA".equals(beanName)) { result = entityBeanHomeA; else if ("EntityBeanHomeB".equals(beanName)) { result = entityBeanHomeB; else ("EntityBeanHomeC".equals(beanName)) { result = entityBeanHomeC; else ("SessionBeanD".equals(beanName)) { result = sessionBeanD; } return result; }
} }
Use JNDI lookup, but declare EJB dependencies via EJB deployment descriptors. 使用JNDI查找,但通过EJB部署描述符声明EJB依赖项。 Again, the container must ensure ensure all dependencies are setup before methods/messages are processed:
同样,容器必须确保在处理方法/消息之前确保所有依赖项都已设置:
@MessageDriven(mappedName="jms/Queue") public class MessageBean implements MessageListener { @MessageDriven(mappedName =“jms / Queue”)公共类MessageBean实现MessageListener {
// as given in the original Question...
} }
Deployment descriptor: 部署描述符:
<enterprise-beans> <message-driven> ... <ejb-name>MessageBean</ejb-name> <ejb-class>com.company.pkg.MessageBean</ejb-class> <messaging-type>javax.jms.MessageListener</messaging-type> <message-destination-type>javax.jms.Queue</message-destination-type> <message-destination-link>ExpenseProcessingQueue</message-destination-link> <ejb-ref> <description> This is a reference to an EJB 2.1 entity bean that encapsulates access to employee records. </description> <ejb-ref-name>ejb/EmplRecord</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>com.wombat.empl.EmployeeRecordHome</home> <remote>com.wombat.empl.EmployeeRecord</remote> <ejb-link>EmployeeRecord</ejb-link> <-- if in same EJB jar --> <-- ../emp/emp.jar#EmployeeRecord if in diff EJB jar --> </ejb-ref> <ejb-local-ref> <description> This is a reference to the local business interface of an EJB 3.0 session bean that provides a payroll service. </description> <ejb-ref-name>ejb/Payroll</ejb-ref-name> <local>com.aardvark.payroll.Payroll</local> <ejb-link>Payroll</ejb-link> </ejb-local-ref> <ejb-local-ref> <description> This is a reference to the local business interface of an EJB 3.0 session bean that provides a pension plan service. </description> <ejb-ref-name>ejb/PensionPlan</ejb-ref-name> <local>com.wombat.empl.PensionPlan</local> <ejb-link>PensionPlan</ejb-link> <-- if in same EJB jar --> </ejb-local-ref> ... </message-driven> ... </enterprise-beans>
Use JNDI lookup but do not declare dependencies using either @EJB annotations or EJB deployment - handle entirely with your own logic, without the container helping. 使用JNDI查找,但不使用@EJB注释或EJB部署声明依赖关系 - 完全使用您自己的逻辑处理,而无需容器帮助。 Use delays/error handling.
使用延迟/错误处理。
Use JBoss proprietary configuration to control deployment order: 使用JBoss专有配置来控制部署顺序:
http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/ http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/
How to order deployment of EJBs and JMS queue config in JBoss 5? 如何在JBoss 5中订购EJB和JMS队列配置?
One way would be to create a dummy-ejb that you inject into your MDB, this way your mdb would not start consuming until that injection can actually take place. 一种方法是创建一个你注入MDB的dummy-ejb,这样你的mdb就不会开始消耗,直到实际发生注入为止。
If the dummy-ejb is bundled with the EJBs you intended to do dynamic lookup on, this should work 如果dummy-ejb与您打算进行动态查找的EJB捆绑在一起,那么这应该可行
My answer here solves a similiar use-case. 我在这里的答案解决了一个类似的用例。
I think that the best approach would be to delay the deployment of your MDB until all your EJBs are up & running. 我认为最好的方法是延迟部署MDB,直到所有EJB都启动并运行。 This is basically approach number 4 in the answer above.
这基本上是上面答案中的第4号方法。
"Use JBoss proprietary configuration to control deployment order: “使用JBoss专有配置来控制部署顺序:
http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/ http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/
How to order deployment of EJBs and JMS queue config in JBoss 5? 如何在JBoss 5中订购EJB和JMS队列配置? "
“
你可以在查找调用周围实现一个带退避的循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.