【问题标题】:Weld cannot find CDI producerWeld 找不到 CDI 生产商
【发布时间】:2017-08-04 15:23:17
【问题描述】:

使用了 WildFly 10.1。在模块中添加了包含带有接口 EzRegistryService 的 jar 文件的单个模块。

生产者代码:

package com.ejbtest;

import org.apache.log4j.Logger;

import javax.ejb.EJB;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Resources {
    private static final Logger log = Logger.getLogger(Resources.class);
    public static final String jndiName = "java:global/ejbtest.main/EzRegistryServiceBean!com.ejbtest.EzRegistryService";

    //also didn't work
    //@Produces
    //@EJB(lookup = jndiName)
    //private EzRegistryService ezRegistryService;

    // didn't work
    @Produces
    public EzRegistryService getEzRegistryService() {
        log.info("getEzRegistryService called");
        try {
            InitialContext ctx = new InitialContext();
            Object service = ctx.lookup(jndiName);
            log.info("Found: " + service);
            return (EzRegistryService) service;
        } catch (NamingException e) {
            log.error("Exception while getting EzRegistryService", e);
            return null;
        }
    }
}

单例豆:

package com.ejbtest;

import org.apache.log4j.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

@Singleton
@Startup
public class MyGateStartup {
    private static final Logger log = Logger.getLogger(MyGateStartup.class);

    //@EJB(mappedName = Resources.jndiName) //works fine
    @Inject
    private EzRegistryService service;

    @PostConstruct
    public void start() {
        log.info("MyGateStartup started");
        //...
    }

    @PreDestroy
    public void end() {
        //...
        log.info("MyGateStartup stopped");
    }

}

WEB-INF 文件夹中的beans.xml:

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

WildFly 无法部署生成的战争文件:

2017-03-14 13:15:05,237 MSC service thread 1-8 INFO  [org.jboss.weld.deployer] WFLYWELD0006: Starting Services for CDI deployment: ejbtest.gate-1.0-SNAPSHOT.war
2017-03-14 13:15:05,241 MSC service thread 1-8 INFO  [org.jboss.weld.deployer] WFLYWELD0009: Starting weld service for deployment ejbtest.gate-1.0-SNAPSHOT.war
2017-03-14 13:15:05,299 MSC service thread 1-6 ERROR [org.jboss.msc.service.fail] MSC000001: Failed to start service jboss.deployment.unit."ejbtest.gate-1.0-SNAPSHOT.war".WeldStartService: org.jboss.msc.service.StartException in service jboss.deployment.unit."ejbtest.gate-1.0-SNAPSHOT.war".WeldStartService: Failed to start service
    at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) [jboss-msc-1.2.6.Final.jar:1.2.6.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [rt.jar:1.8.0_121]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [rt.jar:1.8.0_121]
    at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_121]
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type EzRegistryService with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private com.ejbtest.MyGateStartup.service
  at com.ejbtest.MyGateStartup.service(MyGateStartup.java:0)

为什么 CDI 在 Resources 类中找不到生产者?

【问题讨论】:

  • 生产者被叫到了吗?如果不是,Resources 是否被识别为 bean?因为生产者需要放置在 bean 中才能被 CDI 识别/拾取。
  • @Siliarus,未调用生产者 - 日志中没有“调用 getEzRegistryService”。 “资源是否被识别为 bean” - 必须,因为 bean-discovery-mode="all"。我有类似的工作示例,除了接口和所有类都放在一个战争文件中。
  • 嗯,我明白了。您能否更深入地解释您的部署结构? Resources 类也是在 WAR 中还是在包含接口的模块中?
  • 1 - WildFly 模块位于 WILDFLY_HOME/modules/com/ejbtest/main - 包含具有单一接口 EzRegistryService 的 ejbtest.modules.jar; 2 - ejbtest.main.war - 带有实现 EzRegistryService 的单例 EzRegistryServiceBean; 3 - ejbtest.gate.war 与 Resources 和 MyGateStartup 类(见问题)。
  • 首先,您可以尝试直接注入实现 - 没有生产者,只需从另一个 WAR 注入 EzRegistryServiceBean。但这可能不是你所追求的。因此,另一件事是确保部署的所有三个部分都启用了 CDI。尤其是 WFLY 模块(我感觉 CDI 无法识别该接口类型的任何 bean)。把beans.xml 也放在那里,它应该启用它。我假设带有EzRegistryServiceBean 的WAR 启用了CDI。试试这个改变,看看会发生什么。

标签: wildfly cdi weld


【解决方案1】:

在CDI规范中为written in section 2.5:

没有发现其 bean 类没有定义 bean 注释的生产者方法(在生产者方法中定义)......

您拥有 @Produces 注释方法的类必须是 CDI bean。尝试给它一个范围:)

【讨论】:

    【解决方案2】:

    看起来 CDI 没有管理您的 Resources 课程。

    一旦它只是一个工厂bean,你可以用@ApplicationScoped注解它:

    @ApplicationScoped
    public class Resources {
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-14
      • 2019-06-16
      • 2019-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多