【问题标题】:Weld-SE not starting , no beans archive foundWeld-SE 未启动,未找到 bean 存档
【发布时间】:2018-05-04 09:29:55
【问题描述】:

我正在尝试在我的 Quartz 应用程序中初始化 CDI-SE 上下文,所以我有以下依赖项(maven):

  <dependency>
                <groupId>org.jboss.weld.se</groupId>
                <artifactId>weld-se-core</artifactId>
                <version>2.3.4.Final</version>
            </dependency>

在我的 JobQuartz 中,我有 execute() 方法,其中包含以下内容:

public void execute(JobExecutionContext context) throws JobExecutionException {
        Weld weld = new Weld();
        WeldContainer container = weld.initialize();
        service = container.instance().select(MyService.class).get();
        service.go();
        weld.shutdown();
    }

但我收到以下错误:

Caused by: java.lang.IllegalStateException: WELD-ENV-002009: Weld SE container cannot be initialized - no bean archives found

我的项目是一个WAR,所以我把beans.xml文件放在/src/main/webapp/META-INF/里面,看内容:

<?xml version="1.0"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.2" bean-discovery-mode="all">

</beans>

我将文件复制到/src/main/resource/META-INF,但我得到了同样的错误。

【问题讨论】:

  • 你如何部署或“启动”这个 WAR?通常,您应该将 Weld SE 与 JAR 一起使用。 WAR 通常是使用标准 Weld/weld-servlet 的服务器/servlet(两者都不是您手动启动的)。
  • 附带说明(不能解决您的问题),WeldContainer 实现了Instance,因此您应该能够执行container.select(MyService.class)WeldContainer.instance() 方法已在较新版本中被弃用。
  • @Siliarus,我在 JBoss 中部署我的战争,但石英我需要一些石英没有的范围,所以我使用了焊接 se
  • beans.xml 必须在/src/main/webapp/WEB-INF/,而不是/src/main/webapp/META-INF/
  • 我在这个路径中也有 beans.xml,但我得到了同样的错误

标签: java cdi weld jboss-weld weld-se


【解决方案1】:

如果您尝试启动请求上下文,您有几个解决方案。

  1. 为 CDI 使用 DeltaSpike 的 Quartz 集成 - http://deltaspike.apache.org/documentation/scheduler.html

  2. 使用 BoundRequestContext 以编程方式启动和停止上下文(它是您可以注入的 CDI bean)。

我强烈推荐使用 DeltaSpike 方法,因为它会处理作业自动启动上下文所需的所有设置。

【讨论】:

    【解决方案2】:

    在 cmets 部分的一些对话之后,我想我已经足够了解可以回答你了。

    首先,您不应该自行启动 Weld SE 容器,因为您有两个并排运行的容器(不打算/不支持) - 一个 SE 和一个由容器处理的“经典”。坚持使用容器处理的,它会为您轻松启动。

    现在,我发现您缺少一些作用域激活方法。如果您使用的是一些较新版本的 Weld,您可以使用拦截器,它会在方法之前激活 RequestContext(我想这是您所追求的)并在之后将其拆除。您只需要对 Weld API 的依赖(无论如何都包含在 WFLY 中),然后您只需用它来注释您的方法或类。

    对于上述情况,您需要 Weld 2.4.x。请注意,您可以非常简单地修补您的 WildFly。补丁在Weld website的底部,操作方法可以在here找到。

    如果您要使用 Weld 3/CDI 2.0,那么甚至还有一个内置 bean (RequestContextController) 允许您控制此生命周期。

    正如 Johm Ament 指出的那样,其他选项是 Deltaspike,但这需要您引入另一个依赖项。

    【讨论】:

    • 我认为我找到了另一个解决方案:强制我的 Quartz JOB 从 Rest 客户端调用我的服务,这样我就有了 CDI 上下文。我试过了,效果很好。你怎么看
    • 您没有展示不符合您期望的实际代码,因此很难判断。但是,您所描述的听起来不错,因为通常它只是创建请求,从而触发请求范围上下文。这听起来很有效。
    • 没错,我只是使用 JAX-RS 触发了一个 HTTP 请求。
    猜你喜欢
    • 2016-09-13
    • 1970-01-01
    • 2020-11-05
    • 2020-03-25
    • 2019-07-24
    • 2021-02-19
    • 2021-08-04
    • 1970-01-01
    • 2018-06-16
    相关资源
    最近更新 更多