在 WEB-INF/lib 内的 JAR 中找不到 CDI 实例

Posted

技术标签:

【中文标题】在 WEB-INF/lib 内的 JAR 中找不到 CDI 实例【英文标题】:CDI Instances not found in JAR inside WEB-INF/lib 【发布时间】:2013-12-22 06:29:24 【问题描述】:

我有一个部署到 Glassfish 3.1.2.2 的包含多个模块的 maven JSF 项目。

生成的 EAR 的结构:

|-- lib
|-- META-INF
|-- core-module.jar (packaged as ejbModule by maven)
|   |-- com
|   |   |-- ApplicationSettings.java
|   |   |-- Module.java (Module interface)
|   |   `-- ModuleCORE.java (implementation of Module interface)
|   `-- META-INF
|       `-- beans.xml
`-- presentation-module.war (packaged as warModule by maven)
    |-- WEB-INF
    |   |-- beans.xml
    |   `-- lib
    |       |-- jar-module.jar
    |       |   |-- com
    |       |   |   `-- ModuleEXT1.java (implementation of Module interface)
    |       |   `-- META-INF
    |       |       `-- beans.xml
    |       `-- another-jar-module.jar
    |           |-- com
    |           |   `-- ModuleEXT2.java (implementation of Module interface)
    |           `-- META-INF
    |               `-- beans.xml
    |-- images
    |-- css
    |-- js
    `-- listModules.xhtml

我有三个模块:

核心模块 ext1 模块 ext2 模块

EJB-Module 中存在以下接口:

//Module.java
public interface Module 
    public String getName();

每个模块自己实现接口并返回它们的名字:

ModuleCORE.java ModuleEXT1.java ModuleEXT2.java

在核心模块中,listModules.xhtml 引用以下 bean 以显示模块列表:

//ApplicationSettings.java
@ApplicationScoped
@Named
public class ApplicationSettings 
    @Inject
    @Any
    private Instance<Module> modules;

    public List<String> getModuleList() 
        List<String> result = new ArrayList<String>();
        for (Module module : modules) 
            result.add(module.getName());
        
        return result;
    

现在的问题是只有核心模块的实现在实例列表中。尽管存在相应的META-INF/beans.xml,但未找到WEB-INF/lib 中模块的实现。

谁能向我解释为什么 CDI 无法找到 Module 接口的所有实例?

旁注:WEB-INF/lib 内的 JAR 中的其他 @Named bean 是可注入的/可以在 xhtml 文件中使用。所以基本上 CDI 正在做它的工作,因此正在检查目录。

【问题讨论】:

您使用的是什么版本的 CDI 以及哪个容器? @Templar 我正在使用 Glassfish 3.1.2.2 和 Weld 1.1.4.Final。检查此链接:glassfish.java.net/downloads/3.1.2.2-final.html 根据 Java EE 规范,EJB 模块中的类看不到 WAR 模块中的类。所以,故事到此结束。 @BalusC 感谢您提供的信息。你能想出什么办法来解决这个问题吗? - 基本上我想用 JAR 动态扩展我的项目,包括 classes/resources/xhtml,但也要识别我的扩展。据我所知,以这种方式使用 JAR 的唯一方法是将它们放在 WEB-INF/lib 中并管理 JAR 内 META-INF/resources 下的资源,以便容器找到它们(资源等)。但是如何识别当前存在的扩展仍然存在问题...... 您是否尝试将扩展放在 EAR/lib 中?这个位置在 WAR EJB-JAR 中都是可见的。 【参考方案1】:

一般来说,将 EAR 与 CDI 一起使用被认为充其量是棘手的,更糟糕​​的是毫无结果。如果您对使用 EAR 没有硬性要求,如果您可以将 core-module 放入您的 WEB-INF/lib,您最终会得到您期望的结果。

【讨论】:

没错,但不幸的是,除了presentation-module(在这种情况下是两个网络服务)之外,我还有另外两个需要core-module 的WAR。在这种情况下,我将不得不将其复制到每个 WEB-INF/lib 中,这不是很好。 你是对的,它不会很好。您可以尝试的另一件事是使用可移植扩展将 ApplicationSettingsModuleCORE 安装到 WAR 文件的上下文中。

以上是关于在 WEB-INF/lib 内的 JAR 中找不到 CDI 实例的主要内容,如果未能解决你的问题,请参考以下文章

maven依赖本地非repository中的jar包

在 POM 的 WEB-INF\lib 中添加一个 jar

将 JAR 添加到 IntelliJ 中的 WEB-INF/lib 目录的正确过程是啥

如何签署放置在 maven 中 /WEB-INF/lib 目录中的 JAR 文件

WEB-INF/lib 内容的 JBOSS 排序

如何在eclipse中使用Ivy + IvyDE将不同的jar放到lib和web-inf/lib中