【发布时间】:2016-11-22 09:24:10
【问题描述】:
Glassfish4.1.1(或 Payara41) Java EE 7
[编辑:简单的答案/解决方案可能是“不要那样做,改用 EAR”,但它有一些缺点,见底部]
我正在探索将大型 Web 应用程序模块化的策略。我在 /multi-ant 文件夹下具有以下结构(注意所有项目模块都是 NetBeans Ant 样式的项目版本):
multi-ant/
├── CoreAPIAnt (NetBeans Java Class Library project)
├── CoreEJBAnt (NetBeans EJB Module project)
├── CoreWebAnt (NetBeans Web Application Project, WAR + extra JAR build)
系统(如图所示)仅使用@Local 接口(还有一个@Remote 方面和未显示的独立应用程序客户端)。
CoreWebAnt 可以作为具有 WAR 结构的 JSF Web 应用程序独立运行。
在 CoreEJBAnt 中,我有一个 Element 实体,并且:
@Stateless
public class ElementQuery implements IElementQuery {
IElementQuery 在 CoreAPIAnt 中的位置,这是一个 NetBeans Java 类库项目:
@Local
public interface IElementQuery extends Serializable {
在 CoreWebAnt JSF 网络应用程序中,我有:
...
import javax.inject.Named;
import javax.faces.view.ViewScoped;
@Named(value = "elementManager")
@ViewScoped
public class ElementManager implements Serializable {
@EJB private IElementQuery elementQuery;
目的是让 Web 应用程序模块与 EJB 实现无关,但如果我只是在 CoreWebAnt 中将 CoreAPIAnt 设置为项目依赖项 (dist/CoreAPIAnt.jar)(不参考 dist/CoreEJBAnt.jar),然后部署 CoreEJBAnt和 CoreWebAnt,CoreWebAnt 中使用的 ElementManager 无法解析针对 IElementQuery 的注入,我收到此错误:
Severe: Cannot resolve reference Local ejb-ref name=com.example.multi.core.web.ElementManager/elementQuery,Local 3.x interface =com.example.multi.core.api.IElementQuery,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session
Severe: Exception while deploying the app [CoreWebAnt]
Severe: Exception during lifecycle processing
java.lang.RuntimeException: Cannot resolve reference Local ejb-ref name=com.example.multi.core.web.ElementManager/elementQuery,Local 3.x interface =com.example.multi.core.api.IElementQuery,ejb-link=null,lookup=,mappedName=,jndi-name=,refType=Session
at com.sun.enterprise.deployment.util.ComponentValidator.accept(ComponentValidator.java:374)
如果我也在 CoreWebAnt 中包含 CoreEJBAnt 作为项目依赖项(因此 dist/CoreEJBAnt.jar 在其 /lib 下可用)我可以完全独立运行 CoreWebAnt(并且无需先部署 CoreEJBAnt) . 但这违背了拥有纯接口 CoreAPIAnt 模块的全部目的。
问:当 CoreWebAnt 单独运行且仅依赖于 CoreAPIAnt 时,为什么 Glassfish 不能“看到”并解析部署的 CoreEJBAnt 中的注入实现候选 @Stateless ElementQuery(与 CoreWebAnt 中使用的 CoreAPIAnt 中的 @EJB IElementQuery 相比) .jar ?
如果可能的话,我希望避免 @Remote 的开销(以及通过 RMI 返回的实体的所有后果)并暂时完全留在 @Local 开发生态系统中。
必须从 Web 应用程序引用 CoreEJBAnt 模块并不是世界末日,但它违反了 vs-API 规则,我想了解为什么这里也需要它。
编辑:EAR 方法(经过更多调查)
如果我在 NetBeans 中创建一个空的 EAR 项目(没有嵌套的 EJB 模块或 Web 应用程序模块),我可以在 Java EE 模块上使用添加 Java EE 模块 > 节点添加CoreEJBAnt.jar 和CoreWebAnt.war,它运行良好,没有CoreWebAnt 模块对实现模块CoreEJBAnt 有项目依赖(它只需要CoreAPIAnt)。分解后的分布结构如下:
$ tree -L 3 CoreEAR/dist/gfdeploy/
CoreEAR/dist/gfdeploy/
└── CoreEAR
├── CoreEJBAnt_jar
│ ├── CoreAPIAnt.jar
│ ├── META-INF
│ ├── com ...
│ └── rebel.xml
├── CoreWebAnt_war
│ ├── META-INF
│ ├── WEB-INF
│ ├── index.xhtml
│ └── resources
├── META-INF
│ └── MANIFEST.MF
├── gfv3ee6.dpf
├── lib
│ ├── CoreAPIAnt.jar
│ └── other.jar
它甚至可以很好地引入 lib 下的其他 JAR 库,我还必须放入 CoreWebAnt 的 lib 中才能使其独立运行。
然而,我在使用 JRebel 时遇到了一些新错误,尽管它肯定会在 CoreWebAnt 和 CoreEJBAnt 项目的编辑中捕获和热重载更改。
所以我的问题的答案可能确实是“不要尝试使用独立的网络应用程序,使用 EAR 方法”,但我仍然想知道为什么 Glassfish 不是为让网络应用程序设计的“查看”单独部署的 EJB 模块。我在规范中没有找到任何具体的内容。
【问题讨论】:
-
试过 JBoss Wildfly 只是为了看看它是否与实现相关?
-
@Kukeltje 还没有尝试过 Wildfly,但这是个好主意。我认为问题与 Classloader 分离有关,它在不同的服务器容器实现中可能表现不同。
标签: jsf jakarta-ee glassfish ejb java-ee-7