0

WildFly 10.1 used. In modules added single module that contains jar file with interface EzRegistryService.

Producer code:

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;
        }
    }
}

Singleton bean:

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");
    }

}

beans.xml in WEB-INF folder:

<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 can't deploy resulting war-file:

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)

Why CDI can't find producer in Resources class?

Rustam
  • 1,397
  • 1
  • 13
  • 17
  • Did the producer get called at all? If not, is `Resources` recognized as a bean? Because a producer needs to be placed within a bean to be recognized/picked up by CDI. – Siliarus Mar 14 '17 at 12:59
  • @Siliarus, producer not called - no "getEzRegistryService called" in logs. "is Resources recognized as a bean" - must, because bean-discovery-mode="all". I have similar working example, except that interfaces and all classes was together in single war-file. – Rustam Mar 14 '17 at 13:25
  • Hmm, I see. Could you possibly explain your deployment structure more in depth? Also the class `Resources` is within the WAR or within the module containing the interface? – Siliarus Mar 14 '17 at 14:34
  • 1 - WildFly module at WILDFLY_HOME/modules/com/ejbtest/main - containts ejbtest.modules.jar with single interface EzRegistryService; 2 - ejbtest.main.war - with singleton EzRegistryServiceBean that implements EzRegistryService; 3 - ejbtest.gate.war with Resources and MyGateStartup classes (see question). – Rustam Mar 14 '17 at 14:56
  • Firstly, you could try to inject the implementation directly - no producer and just inject the `EzRegistryServiceBean` from the other WAR. But that's probably not what you are after. So, another thing, make sure that all three parts of your deployment are CDI-enabled. Especially the WFLY module (I have a feeling CDI does not recognize any bean of that interface type). Put `beans.xml` there too and it should enable it. I presume that the WAR with `EzRegistryServiceBean` has CDI enabled. Try it with this change and let's see what happens. – Siliarus Mar 14 '17 at 15:47
  • I don't believe modules are scanned for EJB's so likely the lookup is returning null. – James R. Perkins Mar 15 '17 at 15:53

2 Answers2

1

In CDI specification, it is written in section 2.5:

Producer methods (as defined in Producer methods) whose bean class does not have a bean defining annotation are not discovered....

The class where you have your @Produces annotated method must be a CDI bean. Try giving it a scope :)

0

Looks like CDI is not managing your Resources class.

Once it's just a factory bean, you can annotated it with @ApplicationScoped:

@ApplicationScoped
public class Resources {
    ...
}
cassiomolin
  • 124,154
  • 35
  • 280
  • 359