I'm having a problem using websocket
transport when using Atmosphere. The code is shown below:
When I use long-polling
as a transport, everything works fine. I'm able to call methods on the injected class without any problems. When I configure the client to use websocket
, however, I end up getting a exception saying IllegalStateException: Singleton not set for org.glassfish.main.core.kernel
and the method call fails. I suspect this is due to the way Atmosphere/Glassfish handles WebSockets outside the normal servlet (and therefore, ApplicationContext) environment.
@ManagedService(path = "/rt/test/{id}")
public class TestWebService {
private @Inject TestWebController controller;
@Get
public void onGet(AtmosphereResource r) {
Broadcaster b = controller.getBroadcaster(r.getRequest().getPathInfo(), true);
if(b != null)
r.setBroadcaster(b);
else
r.getResponse().setStatus("Invalid parameter", 400);
}
}
Now the controller:
@ApplicationScoped
public class TestWebController {
private @Inject IdValidator validator;
public void eventHandler(@Observes MyEvent myEvent) {
Broadcaster b = getBroadcaster(myEvent.getId(), false);
if(b != null)
b.broadcast(myEvent.getMessage());
}
public Broadcaster getBroadcaster(String id, boolean create) {
if(validator.validate(id)) {
Broadcaster b = BroadcasterFactory.getDefault().lookup(id);
if(b == null && create)
b = BroadcasterFactory.getDefault().get(id);
return b;
}
return null;
}
}
I've tried different scopes for the controller and just about everything else. If I move the broadcaster create logic into the web service class, it works just fine (without the annotation) but then I loose the ability to validate the id which is somewhat important.
I'm using Glassfish 4 and Atmosphere 2.1.7 with atmosphere-runtime
, atmosphere-annotations
and atmosphere-cdi
jars loaded.
I'm going to try the latest 2.2 release candidate but there are no mentions of any similar issues in the bug tracker so I'm not optimistic.
UPDATE: The same issue occurs with Atmosphere 2.2 RC3.
UPDATE: I was able to make this work by annotating the class with @javax.ejb.Stateful. I have not performed any substantial testing yet to see if there are any side effects but I am able to connect with a websocket and have confirmed that the injection happens correctly. I am using Atmosphere 2.2.0.
This is actually due to a shortcoming in the CDI spec: https://java.net/jira/plugins/servlet/mobile#issue/GLASSFISH-20468
I've had to resort to long polling for now as a result, sadly.