Search code examples
jsfwebsocketmanaged-bean

Inject an application scoped managed bean in a websocket


I'm developing a real time application. I have websockets and application scoped managed bean. I'm trying to access the application scoped managed bean from a websocket but I can't. Is this possible?

This is my websocket and managed bean (application scoped):

@ServerEndpoint("/mediador")
@ManagedBean(eager = true)
@ApplicationScoped
public class Mediador implements Serializable {

@ManagedProperty(value = "#{aplicacion}")
    private Aplicacion aplicacion;
...

And my "Aplicacion" managed bean:

@ManagedBean(eager = true)
@ApplicationScoped
public class Aplicacion implements Serializable {
...

If I try to access in Mediador class to de managed property "aplicacion" it's null so I get a NullPointerException.

Thanks


Solution

  • This is really not right.

    @ServerEndpoint("/mediador")
    @ManagedBean(eager = true)
    @ApplicationScoped
    public class Mediador implements Serializable {
    

    WS (JSR-356 WebSocket) API and JSF API are completely independent from each other. They know nothing from each other and won't take mixed annotations from each other into account.

    Effectively, you end up with two instances of the class. One as a WS managed server endpoint as available by ws://.../mediador, and one as a JSF managed bean as available by #{mediador}. The @ManagedProperty is only recognized by JSF managed bean facility and it'll work in the JSF managed bean instance only.

    Use CDI instead. It works across the entire Java EE web application. Not only in WebSocket endpoints, but also in JSF managed beans, WebServlets, WebFilters, WebListeners, JAX-RS resources, JAX-WS resources, etcetera. Eventually, JSF managed bean facility will be deprecated in favor of CDI. This will happen in Java EE 9 or perhaps already 8.

    @ServerEndpoint("/mediador")
    public class Mediador { // Shouldn't be serializable!
    
        @Inject
        private Aplicacion aplicacion;
    
        // ... (no getter+setter needed!)
    }
    
    @Named
    @ApplicationScoped // javax.enterprise.context 
    public class Aplicacion { // Shouldn't be serializable!
    
        // ...
    
    }
    

    Unrelated to the concrete problem: implementing websockets in JSF rightly is not exactly trivial, certainly not if you'd like to take into account JSF session and view scopes, and would like to be able to target a specific user during push. You'd better look at an existing push component. See also How can server push asynchronous changes to a HTML page created by JSF?