I have a simple setup with just one single Session that backs a JSF xhtml file. Within that I fire an event, expeting that both the same session, and any other session will receive the event on submitting.
However, oddly enough, I can see that during the firing of the event, only the current session receives it, not any other sessions. I am making sure I have two different sessions by using two different browsers (Safari and Firefox in this case).
Do I have the concept of CDI based Events wrong?
The bean backing the session:
package testevent;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.enterprise.event.Event;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Named
@SessionScoped
public class TestEventSession implements Serializable {
private String message = "Start Message";
private String receivedMessage = "";
@Inject
@ForTest Event<String> messageEvent;
Logger LOG = LogManager.getLogger();
public void messageChanged(@Observes(notifyObserver = Reception.IF_EXISTS) @ForTest String message) {
LOG.info("messageChanged <-- "+message);
this.receivedMessage = message;
}
public String getReceivedMessage() {
return receivedMessage;
}
public String getMessage() {
LOG.info("getMessage --> "+message);
return message;
}
public void setMessage(String message) {
LOG.info("setMessage <-- "+message);
this.message = message;
LOG.info("Firing Message Change");
messageEvent.fire(message);
LOG.info("Done Firing Message Change");
}
}
The xhtml file:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
>
<f:view transient="false">
<h:body>
<h:form>
<h:inputText value="#{testEventSession.message}" />
<h:outputText value="#{testEventSession.receivedMessage}" />
<h:commandButton value="Submit"/>
<h:button value="Refresh" />
</h:form>
</h:body>
</f:view>
</html>
The Qualifier used is a very basic one:
package testevent;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ForTest {
}
As part of the debugging output, you can see that only the observer method in the current thread/session receives the event:
10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO testevent.TestEventSession - Firing Message Change
10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO testevent.TestEventSession - messageChanged <-- Start Message #3
10:45:11.213 [GUEST] [http-nio-8080-exec-32] INFO testevent.TestEventSession - Done Firing Message Change
Note that this has been tested with TomEE 7.0.3, which uses assumingely OpenWebBeans 1.7.3.
Related
- @Observes in sessionscoped bean?
- CDI Events, scope of their propagation
- Do CDI Events observed across session scoped JSF backing beans
- CDI spec
Update
It might be that this is an intended feature, however I could not find this explicitly stated in the CDI-Spec. Although the provided example seems to be making sense only when the Observer
only Observes fired events within the same session. In the case of Produces
it clearly states the inter-workings with scoped beans. I think it is rather some documentation lagging in the official spec.
So far other solutions seem to be:
- Manually registering and tracking session beans
- Use of JMS / Message Driven Beans (MDB).
ApplicationScoped
toSessionScoped
- stackoverflow.com/q/4481921/744133. Mine is only different as it fires fromSessionScoped
toSessionScoped
. – YoYo