作为从 JBoss 4.0.4 升级到 5.1 的一部分,我试图在 EAR 成功部署后部署 WAR。JBoss 5.x 不像 4.x 那样支持PrefixDeploymentSorter,这意味着我必须在 WAR 的 jboss-web.xml 中使用 <depends>。
看来我不能依赖 EAR本身,所以我选择了最后部署的 EJB。此 EJB 提供了 WAR 需要的 JNDI 条目。
这是部署目录中不存在 WAR 时部署的 EJB:
2010-03-25 10:47:30,348 INFO [org.jboss.ejb3.session.SessionSpecContainer] (main) Starting jboss.j2ee:ear=my-ear.ear,jar=mypackage-ejb.jar,name=MyFacadeBean,service=EJB3
2010-03-25 10:47:30,350 INFO [org.jboss.ejb3.EJBContainer] (main) STARTED EJB: my.package.MyFacadeBean ejbName: MyFacadeBean
2010-03-25 10:47:30,371 INFO [org.jboss.ejb3.proxy.impl.jndiregistrar.JndiSessionRegistrarBase] (main) Binding the following Entries in Global JNDI:
my/MyFacade/local - EJB3.x Default Local Business Interface
my-ear/MyFacadeBean/local-my.package.MyFacade - EJB3.x Local Business Interface
这是来自 jboss-web.xml 的依赖片段:
<depends>jboss.j2ee:ear=my-ear.ear,jar=mypackage-ejb.jar,name=MyFacadeBean,service=EJB3</depends>
我的问题是: WAR 在“STARTED EJB:”之后立即开始部署,即在 MyFacadeBean 绑定到 JNDI 之前,这会导致 bean 部署失败:
2010-03-25 10:47:39,068 ERROR [my.facade.FacadeFactory] (main) MyFacade not bound
2010-03-25 10:47:39,069 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[my.host.no].[/]] (main) StandardWrapper.Throwable
java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at my.freemarker.servlet.FreemarkerController.setupPojoServiceFactory(FreemarkerController.java:621)
[...]
Caused by: java.lang.RuntimeException: javax.naming.NameNotFoundException: MyFacade not bound
at my.facade.FacadeFactory.getFacade(FacadeFactory.java:61)
WAR 完成部署后,MyFacade 愉快地(嘲弄地?)继续部署并绑定 JNDI 条目。
如果我在 EAR 部署后热部署 WAR,一切都会按预期工作。
我什至想过依赖 EAR 中的虚拟 EJB,并在 jboss-app.xml 中使用 <module-order>strict</module-order> 来强制它作为最后一个模块加载。但是很可惜,JBoss 5.x 也不支持。嗬!
有没有办法依赖 JNDI 条目本身?还有其他方法可以解决这个问题吗?