Singleton EJB observer
seacuke23 Aug 22, 2013 11:52 AMI'm trying to have my singleton EJB be an event observer. The problem I'm having seems particularly related to the fact that my observer method is in an abstract superclass and I need to do some env-entry injection also. I have class EventObserver which is an abstract superclass implementing a business interface and observing an event. There are 2 child classes EventObserverImpl1 and EventObserverImpl2. My application will have only one of these child classes defined in the ejb-jar file as a singleton. What I'm seeing is that the singleton that is defined has it's observer method called as I expect, however the other child class is also constructed. This is especially problematic because the super class injects an env-entry which fails for the non-ejb class.
@Target({FIELD, PARAMETER})
@Retention(RUNTIME)
@Qualifier
public @interface MyEvent {}
@Singleton
@Startup
public class EventFirer {
@Inject
@MyEvent
private Event<String> e;
@Resource
private TimerService ts;
@PostConstruct
public void pc(){
ts.createSingleActionTimer(5000, new TimerConfig(null, false));
}
@Timeout
public void go(){
e.fire("hi");
}
}
public interface MyObserverInterface {
public void observe(String e);
}
public abstract class EventObserver implements MyObserverInterface {
private static final Logger l = Logger.getLogger(EventObserver.class);
@Resource(name="resourceName")
private String resourceName="default";
public EventObserver(){
l.info(this + " -- constructed.");
}
@Override
public void observe(@Observes @MyEvent String e){
l.info(this + " -- " + resourceName + " -- received notification - " + e);
}
protected abstract void doSomething();
}
public class EventObserverImpl1 extends EventObserver {
protected void doSomething() {}
}
public class EventObserverImpl2 extends EventObserver {
protected void doSomething() {}
}
<session> <ejb-name>MyBean</ejb-name> <business-local>com.demo.test.EventTest.test3.MyObserverInterface</business-local> <ejb-class>com.demo.test.EventTest.test3.EventObserverImpl1</ejb-class> <session-type>Singleton</session-type> <env-entry> <env-entry-name>resourceName</env-entry-name> <env-entry-type>java.lang.String</env-entry-type> <env-entry-value>injectedValue</env-entry-value> </env-entry> </session>
.... 09:28:08,031 INFO [com.demo.test.EventTest.test3.EventObserver] (EJB default - 1) com.demo.test.EventTest.test3.EventObserverImpl2@3b9315b1 -- constructed. .... Caused by: java.lang.RuntimeException: Error looking up java:comp/env/resourceName in JNDI at org.jboss.weld.injection.spi.helpers.AbstractResourceServices.resolveResource(AbstractResourceServices.java:51) at org.jboss.weld.util.Beans.injectEEFields(Beans.java:698) ....
I'm using JBoss EAP 6.1.0.GA (AS 7.2.0.Final-redhat-8). I've tried changing the observes annotation by adding notifyObserver=Reception.IF_EXISTS and making the class ApplicationScoped but then the observer doesn't get called at all. If I remove the child class I'm not using as the singleton, the EJB is called as I expect. My current workaround is not to observe in the EJB but have a POJO observe and call the bean.
So my question is, is it possible to have a superclass implement an observer and have it only call the EJB implementation and not attempt to construct all child implementations?
Message was edited by: seacuke23 -- Clarified logging