Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support websocket based server push with CDI #88

Closed
vaadin-bot opened this issue Aug 28, 2013 · 16 comments
Closed

Support websocket based server push with CDI #88

vaadin-bot opened this issue Aug 28, 2013 · 16 comments

Comments

@vaadin-bot
Copy link

Originally by @peholmst


When using Vaadin CDI together with server push (web sockets), you cannot access any session scoped beans from any Vaadin event listeners without getting an exception. The reason is most likely that all requests are done asynchronously when web sockets push is enabled, which in turn means that there is no session info bound to the thread that actually executes them.

Take this as an example:

#!java
@Push
@CDIUI
public class CDIAndPushTestUI extends UI {

    @Inject
    UserInfo userInfo;

    @Override
    protected void init(VaadinRequest request) {
        setContent(new VerticalLayout(
                new Button("Hello World", new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                Notification.show(userInfo.getUser());
            }
        }), new Button("Hello without CDI", new Button.ClickListener() {

            @Override
            public void buttonClick(Button.ClickEvent event) {
                Notification.show("Just a string");
            }
        })));
    }
}

The UserInfo bean is session scoped. A click on the first button will cause an exception, a click on the second button will work as expected. If the @Push annotation is removed, both buttons will work as expected.

I consider this a major issue since session scoped beans is a powerful way of sharing session date between Vaadin UI instances. I tested it on GlassFish 3.1.2.2 with websockets turned on and the grizzly fix installed.

I don't know if this has anything to do with #12021. This problem is also present in Spring, btw.


Imported from https://dev.vaadin.com/ issue #12464

@vaadin-bot
Copy link
Author

Originally by @Legioth


What is the exception thrown by the first button?

I suspect the problem is that the JEE context is not properly initialized by the servlet container when handling push messages, i.e. that this is caused by http://dev.vaadin.com/ticket/12480.

@vaadin-bot
Copy link
Author

Originally by @peholmst


SEVERE: com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method click in com.vaadin.shared.ui.button.ButtonServerRpc
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:170)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
at com.vaadin.server.communication.ServerRpcHandler.handleBurst(ServerRpcHandler.java:214)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:111)
at com.vaadin.server.communication.PushHandler$2.run(PushHandler.java:158)
at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:289)
at com.vaadin.server.communication.PushHandler.onRequest(PushHandler.java:308)
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
at org.atmosphere.container.GlassFishWebSocketSupport.service(GlassFishWebSocketSupport.java:80)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1448)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:219)
at org.atmosphere.websocket.DefaultWebSocketProcessor$2.run(DefaultWebSocketProcessor.java:183)
at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:178)
at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:167)
at org.atmosphere.container.GlassFishWebSocketHandler.onMessage(GlassFishWebSocketHandler.java:137)
at com.sun.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:164)
at com.sun.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.java:75)
at com.sun.grizzly.websockets.DataFrame.respond(DataFrame.java:102)
at com.sun.grizzly.websockets.ProtocolHandler.readFrame(ProtocolHandler.java:151)
at com.sun.grizzly.websockets.WebSocketSelectionKeyAttachment.run(WebSocketSelectionKeyAttachment.java:88)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168)
... 24 more
Caused by: com.vaadin.event.ListenerMethod$MethodException: Invocation of method buttonClick in com.example.cdiandpushtest.CDIAndPushTestUI$1 failed.
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:528)
at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:167)
at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:968)
at com.vaadin.ui.Button.fireClick(Button.java:368)
at com.vaadin.ui.Button$1.click(Button.java:57)
... 29 more
Caused by: java.lang.IllegalStateException: Singleton not set for org.apache.felix.framework.BundleWiringImpl@3ee983b2
at org.glassfish.weld.ACLSingletonProvider$ACLSingleton.get(ACLSingletonProvider.java:110)
at org.jboss.weld.Container.instance(Container.java:54)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:67)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:79)
at com.example.cdiandpushtest.UserInfo$Proxy$_$$WeldClientProxy.getUser(UserInfo$Proxy$$$_WeldClientProxy.java)
at com.example.cdiandpushtest.CDIAndPushTestUI$1.buttonClick(CDIAndPushTestUI.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
... 33 more

@vaadin-bot
Copy link
Author

Originally by @peholmst


On a side note, when implemented in Spring, the exception is that no request has been bound to the currently executing thread.

@vaadin-bot
Copy link
Author

Originally by @Artur-


Need to investigate this for the next CDI version. Possibly requires session access events (#12256).

@vaadin-bot
Copy link
Author

Originally by LukaszByczynski


Above example works with Glassfish 4 and vaadin-cdi-snapshot. Maybe that issue is related to weld container and his proxies for session beans?

@vaadin-bot
Copy link
Author

Originally by @Legioth


Replying to LukaszByczynski:

Above example works with Glassfish 4 and vaadin-cdi-snapshot.

This most likely because the Atmosphere version used in Vaadin 7.1 does not support WebSockets in GlassFish 4. See #12120 for the details about this.

@vaadin-bot
Copy link
Author

Originally by proaccountapp


Updated prioritization date.

@vaadin-bot
Copy link
Author

Originally by @Saulis


This needs some design work and will be implemented in CDI 1.0.

@vaadin-bot
Copy link
Author

Originally by @Artur-


This is really an issue in the CDI and/or websocket specs because they don't take each other into account. Hopefully this will be resolved in a future version of the spec. Can't really classify this as a bug in Vaadin CDI.

We might be able to implement something to get around this for Vaadin CDI 1.0.0 by manually initializing CDI, not 100% sure it is even possible. Until then you should use long-polling if you need CDI support.

References:
https://issues.jboss.org/browse/CDI-370
https://java.net/jira/browse/WEBSOCKET_SPEC-196
https://java.net/jira/browse/JMS_SPEC-121

@vaadin-bot
Copy link
Author

Originally by proaccountapp


Removed prioritization date.

@vaadin-bot
Copy link
Author

Originally by @hesara


Known CDI issues with push (including with web sockets) have been resolved. Note that this only concerns @UIScoped and @ViewScoped beans - request and session scopes are not supported with web sockets in CDI 1.0.

If there are still specific issues, please create new tickets for each issue.

See also #12996 about CDI and background threads.

@mrts
Copy link

mrts commented Jan 22, 2018

Note that you can use @VaadinSessionScoped since CDI 3.0.0 which is compatible with @Push(transport = Transport.WEBSOCKETS_XHR)

@mpittkin
Copy link

For us the solution was to use transport type WEBSOCKET_XHR. This still gives you the benefits of actual push from server to client through websocket, and uses standard XmlHttpRequest for client to server, so you get all the stuff that goes along with it including the active session context.

@mrts
Copy link

mrts commented Jun 30, 2018

@mpittkin, do you use @VaadinSessionScoped or plain @SessionScoped with WEBSOCKET_XHR?

@mpittkin
Copy link

mpittkin commented Jun 30, 2018 via email

@mrts
Copy link

mrts commented Jun 30, 2018

Plain old @SessionScoped. [...] We don't have Vaadin on the class path for service layer.

Perfect, that's exactly what I'm looking for. Case closed, thanks for sharing :)!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants