2

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

Jaime
  • 73
  • 10
  • 1
    Have you tried it? Did you get an error? And are you using JSF bean management or CDI? – Steven De Groote May 19 '15 at 18:24
  • I have edited my post including more information a code – Jaime May 20 '15 at 08:36
  • I'm using JSF bean management. Should I use CDI? – Jaime May 20 '15 at 08:53
  • does the aplicacion have getters / setters? It is required by the managedProperty annotation. Also, you cannot use the managed property in the constructor, consider using @PostConstruct – Sixthpoint May 20 '15 at 14:02
  • Yes, my Mediador class has getter and setter of aplicacion managed property. I don't use the managed property in the constructor, I'd like to use it when my websocket receive a certain message. In the @OnMessage method – Jaime May 20 '15 at 15:40

1 Answers1

3

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?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Ok, I have made those modifications, but when runing the websocket code, the injected field aplicacion is null. I have activated CDI creating an empty beans.xml in my WEB-INF folder. Is not right? Thanks – Jaime May 21 '15 at 08:25
  • By the waym I'm using Tomcat 8.0.15 – Jaime May 21 '15 at 08:36
  • My Java EE version is Java EE 7 Web and I have read in https://netbeans.org/kb/docs/javaee/cdi-intro.html the following: "If you specify Java EE 7 Web as the Java EE version, CDI 1.1 is enabled by default and the beans.xml file is not required". So I have deleted the beans.xml file. It's still not working – Jaime May 21 '15 at 08:51
  • Ok, now I'm using Glassfish 4.1 and works fine. Thanks – Jaime May 22 '15 at 09:27