Closed denis-anisimov closed 3 months ago
This is kind of blocked by the #4227 but it doesn't have to wait when the task will be completely done (and merged). The #4227 should give a way to check whether an application can be used in OSGi. At least there should be a simple way to deploy an application and check the result. Otherwise this needs to be done every time when any OSGi related task is done and this is waste of time to reinvent the testing path every time.
I have some issues with static resources right now.
For the automation tests task I modified root-context tests so that it's OSGi bundle (including UI classes only) : it's a jar file (ui
qualifier).
There is webapp
folder which (I suppose) won't be properly served inside jar bundle.
So I configured the builder-helper
plugin to use resources inside this folder as a part of META-INF/resources
. So far so good. The resources are available inside META-INF/resources
but they are not served as static resources.
That's the very first issue. Should they be served automatically? Servlet specification defines META-INF/resources
folder for the resources inside jar files. But the bundle jar file is not a part of WAR file. It's standalone OSGi bundle.
So as a result servlet context which is used to get the resource in the end doesn't know about static resources inside META-INF/resources
.
OK, may be it's how it's supposed to work.
To be able to expose those resource I register then via HttpService
(which is created inside the bundle because Jetty OSGi bundle doesn't give any HttpService
by the way).
Now resources are available via HTTP.
But we are using servlet context to get resource content by path inside template parser (DefaultTemplateParser
uses service.getResourceAsStream
which delegates to VaadinServletService::getResourceInServletContextOrWebJarAsStream
and its implementation uses the ServletContext::getResourceAsStream
method to get the resource content).
And since the servlet context knows nothing about static resources it returns null
and the parser is unable to parse the template content.
So it's not enough to expose static resources via HTTP but they also should be available via servlet context (or we need to change our code somehow).
To be able to solve this issue I added also resources from the webapp
folder into the root folder.
In the resulting configuration Jetty allows to get resources from the bundle jar and now resources becomes available by their correct path (previously path frontend/something
had to be resolved via META-INF/resources/frontend/something
, now it's available directly as frontend/something
which makes servlet context find it and also via META-INF/resources/frontend/something
which makes it's exposed via HTTP).
But this may be a result of main servlet mapping which is not mapped to the /
but to the view
.
I'm not sure that it will be possible with servlet mapped to the root.
And anyway this config is too cumbersome and inconvenient.
I will keep it for now for tests but once this ticket is fixed we should adjust tests accordingly.
I'm not sure, but I think in my old Vaadin8 integration I had a similar problem.
Back then, I implemented a BundleTracker
(again ;) ) that tracked the bundles with resources and added them via HttpService
and a corresponding HttpContext
, that delegated loading of resources to the bundle that contained the resources.
The BundleTracker
code that adds the resource: https://github.com/Sandared/vaadin8integration/blob/master/de.modularco.vaadin.integration.impl/src/de/modularco/vaadin/integration/impl/OSGiResourceExtender.xtend#L69-L72
The HttpContext
that delegates resource loading: https://github.com/Sandared/vaadin8integration/blob/master/de.modularco.vaadin.integration.impl/src/de/modularco/vaadin/integration/impl/OSGiResourceExtender.xtend#L127-L146
The code is unfortunately in written in Xtend but not so different from Java, so I hope it's readable.
I hope this helps.
Thank you for the examples.
But in fact this is already done almost in the same way in our tests.
The problem is different.
ServletContext
. This class is a part of Servlet specification not OSGi HttpService
specification. You are using HttpContext
to register resources via HTTP. And again I do the same. As I mentioned in the comment : we have DefaultTemplateParser
on the server side and it parses the template file. It doesn't use HTTP to access resources. It uses ServletContext::getResourceAsStream
which has no relation to HTTP and it access resources "locally" ( like ClassLoader
) : get InputStream
by resource path. And this is an issue.
Normally web server is specifically configured to treat some path for static web resources.
If it's configured (e.g. in Jetty resourceBase
can be used for that) then ServletContext
is able to resolve resources by path inside the configured folders and it returns their content via API method.
This is exactly what doesn't happen here.
Ok I got it. I mistook HttpContext
for ServletContext
.
Nevertheless, the OSGi Compendium Specification states that all servlets registered with the same HttpContext
also have the same ServletContext
as described here
If the Servlet
whose ServletContext
is asked by the template processor for the resource is registered with the same HttpContext
as the resources are, then it should be able to find and return the registered resource as stream.
If I'm still getting you wrong, then just ignore this comment. I'm not that deep into Servlets and web stuff as you probably are ;)
A good example in using Vaadin in an OSGi environment can be found at https://github.com/opensecuritycontroller/osc-core/tree/master/osc-ui/src/main/java/org/osc/core/ui It uses the servlet context.
Thank you for the reference. I will look into this.
Regarding to my issue with our flow-testroot-context
module.
At the moment the -ui
classifier jar is the WAB actually (even though it's a jar file).
OSGi compendium says that files in META-INF are protected and are not exposed via web.
In reality the web context path is "/"
for this WAB and static web resources are available from the root folder.
So our frontend
folder in the root may be server via HTTP and is available via servlet context out of the box. So no need to have an activator which register resources via HTTP service.
I made a PR to remove the activator : https://github.com/vaadin/flow/pull/4631.
So there is no issue with the static resource in a WAB file.
But that works only for the resources inside the WAB itself.
We still need register resources if they are outside of a WAB (inside a separate bundle).
But it's not clear : which resources may be required to register ? (not that webjars don't work and should be repackaged) and even if ew register them via HttpService
then what to do with servlet context: they won't be available via Servlet context. Do we have usecases for resources which we want to register to make them available via HTTP and not via servlet context ?
Do we have usecases for resources which we want to register to make them available via HTTP and not via servlet context ?
As discussed, the component related static resources should be made available this way.
But we still need some resources like templates, web component files related to theming; available on the servlet context.
We will first take #4671, fix #4376, create more tests for OSGi (no issue yet) and then we will validate that this works out-of-the-box as it should.
Compatibility mode support, that is required by OSGi add-on, is not supported anymore.
This is similar to #4229 but the static web resources here are not handle by the VaadinServlet. They are handled by the web server directly. Those resources are
frontend
resources like CSS files, HTML files (template files) , JS files. Such files are plain web resources in the application and should be somehow exposed in OSGi.There can be different ways to do this but it should be simple enough for the developer. Similar things are done here https://github.com/mmerruko/framework/commit/687a9009cf3bd2852181848c0c466aac5fe8f5d3 bt it might be this is not applicable at all here.
What needs to be done: create an application, deploy it to OSGi and make sure the static web resources are available there. If the custom way to do this is too complicated or may be improved then provide a way which can be used to simplify this in OSGi environment (see mentioned commit in FW).