I just tried to run a simple Hello World Vaadin app in an OSGi environment (I don’t use Karaf) and ended up with a ClassNotFoundException:
Caused by: java.lang.ClassNotFoundException: de.unia.smds.maf.web.gui.MyUI
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.eclipse.osgi.internal.framework.ContextFinder.loadClass(ContextFinder.java:132)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.vaadin.server.ServletPortletHelper.verifyUIClass(ServletPortletHelper.java:72)
I now annotated both with @Component(…), but I still get the same error.
One way how I got it to show at least the UI is to switch from felix.http to pax.web … I don’t know what the differences are but with pax.web there are no more ClassNotFoundExceptions.
But now it immediatly looses connection after creating the UI and then tries to reconnect the whole time.
Can you tell me in what setting you test your implementation, so that I could recreate it for my setup?
The UI is shown initially, but then I get again a ClassNotFoundException, but this time not for the UI but for a AppWidgetset. Additionally, the UI seems to loose connection to the server immediatly after the first load. When I open the app in debug mode (?debug) then the log says:
261ms First response processed 969 ms after fetchStart
262ms Processing time was 39ms
263ms Referenced paintables: 3
302ms RPC invocations to be sent to the server:
303ms 3 (class com.vaadin.client.ui.ui.UIConnector) :
304ms com.vaadin.shared.ui.ui.UIServerRpc.resize([2560, 1260, 2560, 1260]
)
306ms Sending xhr message to server: {"csrfToken":"e4b9ccd4-e20f-415d-9eda-52191c3f650d","rpc":[["3","com.vaadin.shared.ui.ui.UIServerRpc","resize",[2560,1260,2560,1260]
]],"syncId":0,"clientId":0,"wsver":"8.2.1"}
322ms Server returned 404 for xhr
325ms Reconnecting because of XHR failure
326ms Reconnect attempt 1 for XHR
328ms Re-sending last message to the server...
329ms Sending xhr message to server: {"csrfToken":"e4b9ccd4-e20f-415d-9eda-52191c3f650d","rpc":[["3","com.vaadin.shared.ui.ui.UIServerRpc","resize",[2560,1260,2560,1260]
]],"syncId":0,"clientId":0,"wsver":"8.2.1"}
The Vaadin BootstrapHandler tries to get a WidgetsetInfo in its setupMainDiv method, which calls the getWidgetsetInfo method of UIProvider, which in turn tries to load the class “AppWidgetset”. According to the comments in UIProvider.findWidgetsetClass(), a ClassNotFoundException is a normal case, so I will just throw this Exception in my custom ClassLoader whenever it is asked for this class.
The lost connection seems to stem from false urlPatterns for UIs. After the initial load of an UI that is registered under localhost:8080/test Vaadin sends XHR requests for each interaction (e.g. resizing, clicks, etc.) to the server. The path for these requests are always in form of /UIDL/?.. In our case this would be localhost:8080/test/UIDL. If there is no servlet registered for this path, the Vaadin client receives a malformed response and displays a popup that says: Connection lost… . I fixed this issue in my example application by letting VaadinApplicationHandler change all urlPatterns of UIs to /*
I’m no expert in web development, so the workarounds might not be good. Any improvements for my solution are welcome
I also added a OSGi Vaadin ResourceTracker to the example, as the current solution is not working when I try to add resources that are not within my own bundle. I f you want to add a Resource/Widgetset/Theme to Vaadin you now can just add one of the following lines to your manifest:
If used in an OSGi environment the tracker then finds those bundles and registers their resources with a sepcial HttpContext Object at the HttpService.
In the repository I did this with the Chart.js addon for Vaadin, where I changed its Manifest.
This way you can also use non OSGiyfied addons, just by adding this line to their manifest, Which is a lot easier than adding a new Class/Component to their sourcecode.
I’m sorry for the late reply, I’ve been quite busy and only now I had the chance to look at the issue.
The logic of this OSGi integration is that a Vaadin developer will easily convert an existing Vaadin application to a Vaadin application that can be deployed on OSGi. For example it’s common practice that if you have a theme in your project extending Valo and you need to use constants for the style names you would have a class extending ValoTheme and store the constants there. The same goes for the VaadinServlet which can be annotated with Component and be ready for OSGi (I’m trying to find time to make it possible as well to use UIs as DS in my fork of the framework as you mentioned).
In regards to your findings I would say that it’s incorrect to hardcode the check “AppWidgetset” and check it through the class loader. I don’t know why that request happens, but it might indicate a packaging error or an error in dependencies in my opinion. Other than that I couldn’t look more at the example by Peter Kriens, unfortunately when I was trying to contribute something in the OSGi integration I wasn’t aware of it even though it has existed before I did any work on it and in my opinion is more sophisticated than the solution I made.
It could serve as an alternative add-on in my opinion for use with OSGi, and perhaps your approach bridging parts of the two is the right way to go, I really liked your addition for declaring themes and widgetsets. You can work on your integration futher and publish it as an addon in the Vaadin directory, or make pull requests in the framework repository to improve parts of the existing integration.
Part of your findings seem like a legitimate bug when it comes to the use of the addon with felix. My understanding is that when registering a servlet through pax web it takes into account the Servlet pattern as found in the annotation of the Servlet and configures it, something that felix doesn’t seem to consider. The vaadin-osgi-integration add-on/module doesn’t consider this and it’s something that can and should be fixed. After adding that in place I could run a simple helloworld through bndtools and felix (though I couldn’t get push to work because of missing dependencies). So thank you for pointing this out.
Let me know if I can do something more I can do for solving this.
Noticed the changes you have made to OSGi integration in your Github repo. It is marked for Vaadin 8.5.
Will it make it into 8.5 as it is not included in the alpha1 version.
Also, in your previous posting to Thomas you mentioned a problem with push. Is this sorted in your improvements?
sorry for this long delay, but it seems I completely missed your answer Mirjan and at work our focus switched so I didn’t push my solution further.
I think I’ve found a solution back then that even took care of compiling custom themes on the fly. I hopefully find some spare time in the coming weeks and will try to add my solution as an addon as Mirjan recommended.