当前位置: 首页 > 知识库问答 >
问题:

glassfishnetbeans:为什么jsfweb应用程序作为表示模块需要同时引用ejbapi模块和EJB实现模块

湛玄裳
2023-03-14

玻璃鱼。1.1(或Payara41)Java EE 7

[编辑:简单的答案/解决方案可能是“不要这样做,用EAR代替”,但它有一些缺点,见底部]

我正在探索模块化大型Web应用程序的策略。我在文件夹 /multi-ant下有以下结构(注意所有的项目模块都是NetBeans蚂蚁风格的项目版本):

multi-ant/
├── CoreAPIAnt       (NetBeans Java Class Library project)
├── CoreEJBAnt       (NetBeans EJB Module project)
├── CoreWebAnt       (NetBeans Web Application Project, WAR + extra JAR build)

系统(如图所示)仅使用@本地接口(还有一个@远程方面和独立应用程序客户端未显示)。

CoreWebAnt可以作为具有WAR结构的JSF Web应用程序独立运行。

在CoreEJBant中,我有一个单一的元素实体,并且:

@Stateless
public class ElementQuery implements IElementQuery {

其中IElementQuery位于CoreAPIant中,这是一个NetBeansJava类库项目:

@Local
public interface IElementQuery extends Serializable {

在CoreWebAnt JSF web应用程序中,我有:

...
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)

但是,如果我也将Corejbant作为项目依赖项包含在CoreWebAnt中(因此dist/corejbant.jar在其/lib下可用),那么我可以完全独立地运行CoreWebAnt fine(并且无需首先部署Corejbant)。但是,这违背了仅具有接口的CoreAPIAnt模块的全部目的。

问:为什么当CoreWebant单独运行并且只依赖于CoreAPIAnt.jar时,Glassfish不能“看到”并解决部署的CoreEJBant中的注入实现候选@无状态元素查询(vs@EJB IElementQuery from CoreAPIant)?

如果可能的话,我希望避免@Remote的开销(以及通过RMI返回的实体的所有后果),并暂时完全停留在@Local开发生态系统中。

必须从web应用程序中引用Corejbant模块并不是世界末日,但它打破了vs API规则,我想理解为什么这里也需要它。

编辑:EAR方法(经过更多调查)

如果我在NetBeans中创建一个空的EAR项目(没有嵌套的EJB模块或Web应用程序模块),那么我可以使用javaee模块节点上的addjavaee模块来添加CoreEJBAnt。jar和corewbant。war,并且它运行良好,没有CoreWebAnt模块对实现模块CoreJBant的项目依赖性(它只需要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和Corejbant项目中编辑的更改。

因此,我的问题的答案可能确实是“不要尝试使用独立的web应用程序,使用EAR方法”,但我仍然有兴趣知道为什么Glassfish的设计不是为了让web应用程序“看到”单独部署的EJB模块。我没有在说明书中找到任何关于它的具体信息。

共有1个答案

党浩阔
2023-03-14

爪哇™ 平台,企业版(JavaEE)规范,v7在应用程序组装和部署部分提供了对运行时类可见性要求的清晰描述。

这是所有完整的JavaEE服务器(如GlassFish和WildFly)实现的。

单独部署的组成部分(部署单位)的隔离是故意的。

 类似资料:
  • 我有一个Gradle多模块项目,有一个用于调用第三方服务的公共模块。在公共模块中使用Webclient,因此webflux中包含starter。 实施组织。springframework。启动:Spring启动启动webflux' 因为我已经包括了SpringBootStarterWebFlux,所以它正试图构建为一个bootJar,并期待主应用程序。如果我使用一个主应用程序,它构建的很好。但是,

  • 我有1个应用程序和2个模块 框架结构 但我不能在MyApp中使用MyModule的文件。IDE显示我“无法访问”错误,我想扩展一个MyModule类的类。而且它不是从MyModule创建类的,有人对此有想法吗?怎么了?

  • 我在NetBeans中创建了一个带有EJB模块和web模块的Java EE应用程序。业务逻辑驻留在EJB模块内部的EJB中。web模块的托管bean是否可以访问EJB模块内部的EJB?怎么做? (JDK 1.7、Java EE 6、Glassfish 3.1.2.2、NetBeans IDE 7.2)

  • 问题内容: 我注意到我今天想解释的东西很奇怪。我不是100%不确定如何将其表达为一个问题,所以google是不可能的。由于某些奇怪的原因,日志记录模块无权访问模块logging.handlers。如果您不相信我,请自己尝试: 谁能解释为什么会这样? 问题答案: 在Python中,需要先导入模块,然后才能对其进行访问。仅导入日志记录模块。碰巧这是一个带有子模块的软件包,但是那些子模块仍然不会自动加载

  • 另一个类比了解Angular 2模块的是类。 在类中,我们可以定义公共或私有方法。 公共方法是我们代码的其他部分可以用来与之交互的API,而私有方法是隐藏的实现细节。 以相同的方式,模块可以导出或隐藏组件,指令,管道和服务。 导出的元素可被其他模块使用,而未导出(隐藏)的元素只是在模块本身内部使用,并且不能被我们的应用程序的其他模块直接访问。 模块的基本使用 为了能够定义模块,我们必须使用装饰器

  • 我们已经讲到了如何使用模块名称作为调用的一部分,来调用模块中的函数,如示例 7-7 中所示的 nested_modules 函数调用。 文件名: src/main.rs 示例 7-7:通过完全指定模块中的路径来调用函数 如你所见,指定函数的完全限定名称可能会非常冗长。所幸 Rust 有一个关键字使得这些调用显得更简洁。 Rust 的 use 关键字能将你想要调用的函数所在的模块引入到当前作用域中,