Search code examples
jakarta-eecdimessage-driven-bean

Injecting message driven beans


In an enterprise application, I'm trying to inject MessageDriven beans into the web-application (to a REST service) using netBeans 8.1. I dont get any warnings in the IDE, however, at deploy time i get the following error:

Severe: Exception while loading the app : CDI deployment failure:WELD-001408: Unsatisfied dependencies for type StatisticsBean with qualifiers @Default at injection point [BackedAnnotatedField] @Inject private sv.mycompany.rest.RestService.statisticsBean

Here is one of the beans i'm trying to inject:

@MessageDriven(mappedName = "dzsobTopik")
public class StatisticsBean implements MessageListener{

private  Logger LOGGER = Logger.getLogger(StatisticsBean.class.getSimpleName());
private int scheduledJobs = 0;

@Inject
private JMSContext jmsContext;

private static Map<Integer, Boolean> results = new HashMap<>();

public StatisticsBean() {
}



public static Map<Integer, Boolean> getResults() {
    return results;
}

public void setResults(Map<Integer, Boolean> results) {
    StatisticsBean.results = results;
}



@Override
public void onMessage(Message message) {
    if(message instanceof JobScheduledMessage){
        scheduledJobs++;
    }
    else if(message instanceof JobCompletedMessage && scheduledJobs>0) {
        if(((JobCompletedMessage) message).getTimestamp()<5){
            LOGGER.log(Level.INFO, "Job successful!");
                results.put(((JobCompletedMessage) message).getJobnumber(), Boolean.TRUE);
                scheduledJobs--;
        }
        else {
                LOGGER.log(Level.INFO, "Job unsuccessful!");
                results.put(((JobCompletedMessage) message).getJobnumber(), Boolean.FALSE);
                scheduledJobs--;
            }
    }
}
}

And here is my restService class:

@Path("/start")
@Produces(MediaType.APPLICATION_JSON)
public class RestService {

@Inject
private JobScheduler jobScheduler;

@Inject
private StatisticsBean statisticsBean;

@Inject
private FastWorker fastWorker;

@Inject
private SlowWorker slowWorker;

@Inject
private NormalWorker normalWorker;

@GET
@Produces(MediaType.TEXT_PLAIN)
public String startSimulation() throws InterruptedException{
    jobScheduler.queueNewJobs();
     return "Started simulation";
}

@GET
@Path("/jobresult")
public Map<Integer,Boolean> getJobResults(){
    return StatisticsBean.getResults();
}

}

I have beans.xml in both the ejb and the web module, with discovery mode set to "all" in both cases. What could be the problem?


Solution

  • Why would you inject it at the first place? Those are not session beans and are not intended for injections. Message-driven beans are accessed by JCA resource adapter (like JMS implementation) through the special messaging interface. MDBs may be pooled, so keeping any state inside them is meaningless. In Java EE, using technologies without prior understanding would always result in pain, so, consider inspecting EJB documentation regarding those beans.

    In your particular case, if you really need to store something for further processing, you sould consider using either singleton session bean or application scoped CDI bean instead. Those are capable of maintaining meaningful state and can be injected into any managed bean, including MDBs.