【问题标题】:CDI beans inside .jar are not found by the container (Unsatisfied dependencies)容器找不到 .jar 中的 CDI bean(不满足的依赖项)
【发布时间】:2016-12-30 22:52:52
【问题描述】:

我创建了一个 Java 项目作为其他项目的库,从而减少项目之间的代码重复。此 lib 项目导出到 jar 以包含在 Web 项目(WAR,而不是 EAR)中。

在 Web 项目中(这些类已被删除),一切都照常工作,而所有类都保留在它们上面 ─ 简单和复杂对象(具有生产者和设置的对象)的注入正常工作.

在删除 Web 项目的这些类并将具有这些相同类的 jar 添加到 Web 项目(在 Maven 项目中的 pom.xml 中设置此库)之后,一切都正常编译,就像以前一样。但是在启动服务器时,容器在 CDI 启动期间找不到现在存在于 jar 中的类(CDI bean),从而产生这个(著名的)错误:

WELD-001408: Unsatisfied dependencies for type Session with qualifiers (...)

已将 beans.xml 添加到 src/main/resources(在 WELD 和 CDI 文档中表示)的 META-INF 文件夹中作为项目的根文件夹。

以下是 jar 中的 bean(Session、SessionFactory 和 ExampleLogger)示例,它们需要注入到其他项目中(并且在该类在 Web 项目中时已经正常工作)但现在不是 被 CDI 发现:

public class HibernateConnectionFactory {

    @Produces
    @ApplicationScoped @ConnectionBaseExample
    public SessionFactory createSessionFactoryExample() {
        Configuration configuration = new Configuration();
        configurarSessionFactory(configuration, "baseExampleDS");
        ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();

        return configuration.buildSessionFactory(registry);
    }

    @Produces
    @RequestScoped @ConnectionBaseExample
    public Session createSessionExample(@ConnectionBaseExample SessionFactory sessionFactory) {
        return sessionFactory.openSession();
    }

    public void destruirSessionExemplo(@Disposes @ConnectionBaseExample Session session) {
        if (session.isOpen()) {
            session.close();
        }
    }
}
public class ExampleLoggerProducer {

    @Produces
    public ExampleLogger createLogger(InjectionPoint injectionPoint) {
        return new ExampleLogger(injectionPoint.getMember().getDeclaringClass());
    }
}

问题出现在 Maven 项目和非 Maven 项目中。有没有人遇到过这个问题?有谁知道容器可以找到 jar 中的 bean 的解决方案吗?提前感谢您,对英语不好表示抱歉。

Java EE7、CDI 1.1、WELD 2.1、服务器 WildFly 8.1

【问题讨论】:

  • 应该工作,所以你的设置有问题。你确定这个罐子包括在战争中吗?您是否更改了注释(限定符)的包名称?您是否在 jar 项目中创建了一个新的简单 bean 并尝试将其注入到战争中。这行得通吗?
  • 是的,我试过了。不久前再次尝试,我找到了解决方案 ─ 我将 beans.xml 放在项目 root 文件夹 内的 META-INF 文件夹中,并且成功了!这与 WELD 文档中关于如何在 jar 中使用 CDI bean 的描述背道而驰,其中说放置 beans.xml 的位置在 src/main/resources/META-INF 中,但没关系。无论如何,谢谢 Guenther。
  • 请查看您的beans.xml。是否指定bean-discovery-mode="annotated",如果是,请注释生产者类,至少使用ApplicationScoped
  • 我尝试了“annotated”和“all”,但问题是我导出 jar 的方式,使用 Eclipse 的导出 jar 向导而不是使用 Maven 来执行此操作。谢谢@maress

标签: jakarta-ee cdi weld jboss-weld


【解决方案1】:

一段时间后再次尝试,我找到了解决方案 ─ 我将 beans.xml 放在 project root 文件夹内的 META-INF 文件夹中,它成功了!这与 WELD 文档中关于如何在 jar 中使用 CDI bean 的描述背道而驰,其中说放置 beans.xml 的位置在 src/main/resources/META-INF 中,但没关系。也许在某些 Maven 项目中,确实如此。

[UPDATE] 这很有效,因为我使用 Eclipse 的导出 jar 向导而不是使用 Maven 来构建 jar。使用 Maven 应该可以与 src/main/resources/META-INF 中的 beans.xml 一起正常工作。

希望这也可以帮助其他人解决这种情况。

【讨论】:

  • 在这种情况下,您的 Maven 设置中处理资源的方式有问题。也许您在 pom 中重新定义了如何复制资源? src/main/resource/META-INF/beans.xml 记录的设置如果您没有弄乱任何东西,肯定可以工作,这可以在许多帖子中看到,例如stackoverflow.com/questions/13056336/…
  • 我认为它是这样工作的,因为您使用 Eclipse 导出 jar 文件,而不是使用 Maven 构建的人工制品。理想情况下,您会使用 Maven 来构建您的分布式工件,因为这是一个可重复的过程,而 Eclipse 导出可能会根据用户的个人设置而有所不同。
  • @SteveC 是对的。我正在使用 Eclipse 的导出 jar 向导进行构建,而不是使用 Maven 来执行此操作。使用 Maven 在指定位置使用 beans.xml 构建工作正常。谢谢你们,非常感谢你们的帮助和关注!
【解决方案2】:

我在 Eclipse 中遇到了两个项目的相同症状。 WAR 项目从导入的 JAR 库项目中注入了实现。 Maven 编译正确,但在本地运行时环境中运行时,bean 管理器无法解析库 bean,不稳定并发送提到的异常。

Eclipse 不使用 Maven 来准备调试代码,并且它的 Project Facets 是使用 Maven 插件配置的。 Maven 依赖项在两个项目中都匹配,但问题出在 Eclipse 项目配置中。

我的环境是 JBoss EAP 6.4,我发现 Maven 插件设置了 JAR CDI 项目方面但保留了默认版本 2.0。 Run-time 实际上支持 CDI 1.0,并且 WAR 项目中的 CDI 项目方面有正确的版本。

在我的例子中,WAR 和导入的 JAR 项目中不同版本的 CDI 项目方面导致了这个异常。需要手动更正 Eclipse 项目方面的版本。运行时环境和 Eclipse 项目方面的匹配 CDI 版本问题消失了。

【讨论】:

    猜你喜欢
    • 2022-01-21
    • 2017-01-14
    • 2019-07-20
    • 2010-12-06
    • 2014-04-07
    • 2015-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多