-
Notifications
You must be signed in to change notification settings - Fork 1
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
OSGi: Make sure that Push with Websocket transport works in OSGi #64
Comments
Some investigation notes: Seems those dependencies have websocket impl for jetty:
BUT I have no idea whether they are those deps which we need to enable proper websocket support in Felix Jetty. The functionality in those bundles heavily relies on I've made a very very ugly hack in the
This code shows how things are complicated : the Then I initialize servlet context via Also I had to register a servlet in this way:
Otherwise there will be an exception again related to the fact that in OSGi the servlet registered in the servlet context is a proxy for Jetty servlet (and there is some code which tries to find a servlet by its name which differs). With this config I'm able at least get But Push with websockets still doesn't work. So there are so many questions and the very basic questions are about proper project setup so that websocket works with web server in OSGi. |
And final questions: what's needed from Flow to be able to support web sockets Push in OSGi. It might be that we will need to make changes in the current impl just like we added route registration logic in OSGi. And it's not clear whether we need to do anything in Flow at the moment: there are too many ways to go (and many wrong ways) in different areas (Felix Jetty issues? Websocket support in Jetty issues? Atmoshpere issues? Project config issues ? Our issues ?) |
It's not clear whether there is a bug or not. But also there is at least one issue: |
Apprently for Vaadin Framework 8.7, Push with web sockets works on Karaf 4.2.3 and the included Jetty 9.1.14 |
How it can be seen ? |
Apparently it is working fine in a customer project using 8.7.1 and the recently released Karaf version linked ^. |
Ah, OK. Another question is : how do they deploy their web application into Karaf. We are trying to deploy a web application as a standalone bundle without any dep inside it. |
Hi, If so this can be achieved in OSGi by either annotating it with the right annotations as described here @Component
@HttpWhiteboardListener
public class JSR356WebsocketInitializer implements ServletContextListener {...} Unfortunately with the shift from plain properties to If you are unable to make this version shift then you just can declare the property by hand instead of using @Component(property= {HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER + "=true"})
public class JSR356WebsocketInitializer implements ServletContextListener {...} This solution also works with the old versions of felix. As I understand it from reading your code in I did this in my old sketch for a Vaadin OSGi integration: https://github.com/Sandared/flow-osgi/blob/master/flow.osgi.integration/src/main/java/io/jatoms/flow/osgi/integration/FlowOsgiRouteRegistryInitializer.java Kind regards, |
An additional note regarding Karaf: Karaf is a very powerful application container, but might not be the best choice to verify an OSGi integration of Flow, because of the aforementioned points. Kind regards, |
That's only one part of the problem. I didn't know about In your case you are adding a service via DS , I've been trying to add it programatically. It doesn't work because of this: http://felix.apache.org/documentation/subprojects/apache-felix-http-service.html#servlet-api-events. |
The reason your programmatically registered service is not registered is the same as why my service with Try to change the value of the property to be a String instead of a boolean, i.e., Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put("osgi.http.whiteboard.listener", "true");
context.registerService(ServletContextListener.class,
new ServletContextListener() {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Init");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}, props); This should work with the older versions of Felix too. |
We don't use Karaf in Flow in our tests. So there is no any uncertainty about OSGi support in Flow. |
Ah, alright. Thanks for the info. I will try. |
We face the same issue with Equinox 4.7, VAADIN 8.6.4, Jetty 9.4.14/Tomcat 8.5.37, Atmosphere 2.4.30 (VAADIN1), when we try to use Vaadin UI w/ Push and WebSocket transport distributed as OSGi component. The PUSH always fallback to LONG_POOLING no matter if we registered the VaadinServlet to a Felix Jetty HttpService provider, Equinox Jetty HttpService provider or Equinox ServletBridge HttpService provider. Our application is a VAADIN gateway in front of a micro-service ecosystem where PUSH plays quite a important role. It is required for gateway to run in any web-container as long as an HTTPService is available in OSGi runtime via native support or bridges, therefore we can not limit ourselves just to support Jetty as HttpService provider. Even we knew it is not enough, we want to see if PUSH runs with Jetty and WebSocket ServerContainer enabled. For that we registered a ServletContextListener via DS, where on contextInitialized we did: This was not enough, by first attempt, JSR365 async support does not start because it can not find a servlet-path to map to. Afterwards we force path mapping by manually providing the mapping: Using Equinox HttpService provider, we were not able to start JSR365 async support:
Using Felix HttpService provider, we were able to start JSR365 async support:
Nevertheless we were not able to use VAADIN PUSH due to client side error:
|
Looking into Vaadin 13 this would be a showstopper for my projects. On Vaadin 8 i got push working on Karaf with SCR and pax-web HTTP-Whiteboard and these settings on the Vaadin-Servlet: and the UI class: and using following Vaadin bundles:
|
Deployed on Karaf 4.2.4, using Apache ServiceMix :: Bundles :: javax.websocket-api: 45 │ Active │ 80 │ 9.3.1 │ ph-commons |
The log is displaying 2 warnings and push is not working: 2019-03-22T10:56:06,406 | WARN | paxweb-config-1-thread-1 | ServletContainerInitializerScanner | 106 - org.ops4j.pax.web.pax-web-api - 7.2.8 | failed to parse and instantiate of javax.servlet.ServletContainerInitializer in classpath 2019-03-22T10:56:06,516 | WARN | paxweb-config-1-thread-1 | ServletContainerInitializerScanner | 106 - org.ops4j.pax.web.pax-web-api - 7.2.8 | failed to parse and instantiate of javax.servlet.ServletContainerInitializer in classpath After opening the webpage it is reloading if the frequency of my server-side updates and displaying errors in the webpage: Cookies disabled ...and in the Karaf log: 2019-03-22T11:45:39,866 | WARN | qtp1194084166-125 | HttpChannel | 91 - org.eclipse.jetty.util - 9.4.12.v20180830 | / |
OK, got manual push working now with the following settings on the project-base-osgi project: Main view: @route("") FixedVaadinServlet: @WebServlet(asyncSupported = true) Only the following exception keeps popping up in the logs: 2019-03-22T12:22:20,721 | INFO | activator-1-thread-2 | CommandExtension | 35 - org.apache.karaf.shell.core - 4.2.4 | Registering commands for bundle org.apache.karaf.http.core/4.2.4 |
Client side: Request URL:http://localhost:8181/?v-r=push&v-uiId=5&v-pushId=b13a6930-8591-4721-a42e-1b5a31df9dde&X-Atmosphere-tracking-id=0&X-Atmosphere-Framework=2.3.2.vaadin1-javascript&X-Atmosphere-Transport=websocket&Content-Type=application/json; charset=UTF-8&X-atmo-protocol=true |
Great, after a redeploy of the Servicemix web-socket bundle this exception disapears, it seems that Karaf did not do a complete reload of these classes and kept using the default javax.websocket classes. |
Oh, i forgot to mention i changed the VaadinServletRegistration class: @WebServlet(asyncSupported = true, urlPatterns = "/*") // @WebServlet(asyncSupported = true, urlPatterns = "/*") // @activate |
I am using OSGi, Jetty, and Vaadin with Push. However, I am not using Whiteboard Pattern. I prefer to have Jetty jars embedded in a bundle because I require further deep integrations. I also needed to handle some trouble with Push. In my case the solution was a patch in the Manifest of the "jakarta.websocket-api-1.1.2.jar" (and maybe - I am not sure anymore - using spifly [1]). Add the following header to jakarta.websocket-api, also explained in [2]: Require-Capability: osgi.serviceloader;filter:="(osgi.serviceloader=javax.websocket.server.ServerEndpointConfig$Configurator)";cardinality:=multiple,osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.6))" I also had to add the following header to my bundle embedding the Jetty jars: Provide-Capability:osgi.serviceloader;osgi.serviceloader="javax.servlet.ServletContainerInitializer",osgi.serviceloader;osgi.serviceloader="javax.websocket.server.ServerEndpointConfig$Configurator" [1] https://aries.apache.org/modules/spi-fly.html |
Here are also comments about WS in Karaf: #63 (comment) |
Moving this ticket into OSGi repo. |
This ticket follows up vaadin/flow#5081.
It's quite complicated even just describe the ticket.
The simplest description is:
Use base-starter-flow-osgi and add @Push annotation to MainView.java.
Push won't work.
By default the transport is Websockets. And that's the reason why it doesn't work. It's possible to use Long polling as a transport.
Note that it's not clear whether this issue is a project configuration issue or it's an issue in our websocket support with OSGi.
First of all you should add websocket api dependency to the project :
But this is not enough. Push with websockets won't work.
The reason why it doesn't work is:
ServerContainer is null
in theorg.atmosphere.container.JSR356AsyncSupport
here:And that's the most complicated thing: it's totally unknown which bundle should set the attribute in the
ServletContext
.Apparently there should be some websocket implementation bundle for jetty which should set the attribute at the servlet initialization phase.
This is normally done either by a
ServletContainerInitializer
orServletContextListener
.The problem is : neither one nor another doesn't work in OSGi out of the box (at least they doesn't work in Felix jetty).
So the questions are:
It's not even clear whether it's possible to configure Felix Jetty at all to work properly with Atmosphere so that
JSR356AsyncSupport
doesn't fail.May be it's just not possible at all and we should use another OSGi container/ web container ?
If it's possible then what bundles should be deployed in addition to
javax.websocket-api
to enable websocket support (not a generic web sockets support but makeJSR356AsyncSupport
works as it should)?If we find those bundles and deploy then then what's required from Flow to make websocket Push works ?
We have
JSR356WebsocketInitializer
which is aggregated byServletContextListeners
(which is@WebListener
) and it's not activated in OSGi out of the box.So this is one thing in addition to all other which we should take care.
Read also comments in another ticket starting from this one : vaadin/flow#5081 (comment).
The text was updated successfully, but these errors were encountered: