Glassfish+NetBeans:为什么 JSF Web App 作为展示模块需要同时引用 EJB API 模块和 EJB 实现模块
Glassfish+NetBeans: Why does JSF Web App as presentation module need to reference both EJB API module and EJB implementation module
Glassfish4.1.1(或 Payara41)
Java EE 7
[编辑:简单的 answer/solution 可能是 "don't do it that way, use an EAR instead",但它有一些缺点,见底部]
我正在探索模块化大型网络应用程序的策略。我在文件夹 /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 中,我有一个元素实体并且:
@Stateless
public class ElementQuery implements IElementQuery {
其中 IElementQuery 在 CoreAPIAnt 中,它是一个 NetBeans Java Class 库项目:
@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 实现无关,但是如果我只是将 CoreAPIAnt 设置为 CoreWebAnt 中的项目依赖项 (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)
如果我 也 将 CoreEJBAnt 作为项目依赖项包含在 CoreWebAnt 中(因此 dist/CoreEJBAnt.jar 在其 /lib 下可用)我可以 运行 CoreWebAnt 完全独立(无需首先部署 CoreEJBAnt)。 但这违背了拥有仅接口核心APIAnt 模块的全部目的。
问:为什么 Glassfish 不能 "see" 并解析已部署的 CoreEJBAnt 中的注入实现候选 @Stateless ElementQuery(对比 CoreAPIAnt 中使用的 @EJB IElementQuery CoreWebAnt) 当 CoreWebAnt 单独 运行 并且只依赖于 CoreAPIAnt.jar ?
我希望尽可能避免 @Remote 的开销(以及实体通过 RMI 返回的所有后果)并暂时完全留在 @Local 开发生态系统中。
必须从 Web 应用程序引用 CoreEJBAnt 模块并不是世界末日,但它打破了 vs-API 规则,我想了解为什么这里也需要它.
编辑:EAR 方法(经过更多调查)
如果我在 NetBeans 中创建一个空的 EAR 项目(没有嵌套的 EJB 模块或 Web App 模块),我可以在Java EE Modules 节点添加 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 项目中捕获并热重新加载编辑中的更改。
所以我的问题的答案可能确实是 "don't try to use the standalone web app, use the EAR approach",但我仍然想知道为什么 Glassfish 没有设计为让 Web 应用 "see" 单独部署EJB 模块。我没有在规格中找到任何关于它的具体信息。
Java™ 平台企业版 (Java EE) 规范 v7 提供了对运行时要求的清晰描述 class 在 应用程序组装和部署 部分的可见性。
这是所有完整的 Java EE 服务器(例如 GlassFish 和 WildFly)实现的。
单独部署的组件(部署单元)的隔离是有意的。
Glassfish4.1.1(或 Payara41) Java EE 7
[编辑:简单的 answer/solution 可能是 "don't do it that way, use an EAR instead",但它有一些缺点,见底部]
我正在探索模块化大型网络应用程序的策略。我在文件夹 /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 中,我有一个元素实体并且:
@Stateless
public class ElementQuery implements IElementQuery {
其中 IElementQuery 在 CoreAPIAnt 中,它是一个 NetBeans Java Class 库项目:
@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 实现无关,但是如果我只是将 CoreAPIAnt 设置为 CoreWebAnt 中的项目依赖项 (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)
如果我 也 将 CoreEJBAnt 作为项目依赖项包含在 CoreWebAnt 中(因此 dist/CoreEJBAnt.jar 在其 /lib 下可用)我可以 运行 CoreWebAnt 完全独立(无需首先部署 CoreEJBAnt)。 但这违背了拥有仅接口核心APIAnt 模块的全部目的。
问:为什么 Glassfish 不能 "see" 并解析已部署的 CoreEJBAnt 中的注入实现候选 @Stateless ElementQuery(对比 CoreAPIAnt 中使用的 @EJB IElementQuery CoreWebAnt) 当 CoreWebAnt 单独 运行 并且只依赖于 CoreAPIAnt.jar ?
我希望尽可能避免 @Remote 的开销(以及实体通过 RMI 返回的所有后果)并暂时完全留在 @Local 开发生态系统中。
必须从 Web 应用程序引用 CoreEJBAnt 模块并不是世界末日,但它打破了 vs-API 规则,我想了解为什么这里也需要它.
编辑:EAR 方法(经过更多调查)
如果我在 NetBeans 中创建一个空的 EAR 项目(没有嵌套的 EJB 模块或 Web App 模块),我可以在Java EE Modules 节点添加 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 项目中捕获并热重新加载编辑中的更改。
所以我的问题的答案可能确实是 "don't try to use the standalone web app, use the EAR approach",但我仍然想知道为什么 Glassfish 没有设计为让 Web 应用 "see" 单独部署EJB 模块。我没有在规格中找到任何关于它的具体信息。
Java™ 平台企业版 (Java EE) 规范 v7 提供了对运行时要求的清晰描述 class 在 应用程序组装和部署 部分的可见性。
这是所有完整的 Java EE 服务器(例如 GlassFish 和 WildFly)实现的。
单独部署的组件(部署单元)的隔离是有意的。