On Thu, Jan 01, 2026 at 10:10:10AM +0100, Steinar Bang wrote:
> >>>>> "Chaz Kettleson via dev" <[email protected]>:
>
> > 2. The fact that if you create your own context, you need to pass the
> > bundle to the constructor of ServletContextHelper in order for it to
> > resolve resources correctly (this drove me completely nuts)
> [...]
>
> > @Component(
> > service = ServletContextHelper.class,
> > property = {"osgi.http.whiteboard.welcome.file=index.html"})
> > @HttpWhiteboardContext(name = "dashboard", path = "/dashboard")
> > @HttpWhiteboardContextSelect("(" + HTTP_WHITEBOARD_CONTEXT_NAME +
> > "=dashboard)")
> > @HttpWhiteboardResource(pattern = "/*", prefix = "/static")
> > public class DashboardServletContextHelper extends ServletContextHelper {
>
> > @Activate
> > public DashboardServletContextHelper(final BundleContext bundleContext) {
> > super(bundleContext.getBundle());
> > }
> > }
>
> Hm... my context helpers have far less annotations and no injection of
> bundlecontext and they seem to work...?
>
> https://github.com/steinarb/sampleapp/blob/master/sampleapp.web.security/src/main/java/no/priv/bang/sampleapp/web/security/SampleappServletContextHelper.java
>
Firstly, ignore the property "osgi.http.whiteboard.wecome.file" this is
not a real thing (I thought it worked but I forgot I had a filter doing
it).
Your example works fine, but would not work for loading static
resources. My example is a bit convoluted. Probably should have done
something like this:
@Component(service = ServleContextHelper.class)
@HttpWhiteboardContext(name = "dashboard", path = "/dashboard")
public class DashboardServletContextHelper extend ServletContextHelper {
@Activate
public DashboardServletContextHelper(final BundleContext bundleContext) {
super(bundleContext.geBundle());
}
}
@Component(service = DashboardResources.class)
@HttpWhiteboardContextSelect("(" HTTP_WHITEBOARD_CONTEXT_NAME + "=dashboard)")
@HttpWhiteboardResource(pattern = "/*", prefix = "/static")
public class DashboardResources {}
The expectation is that I have a src/main/resources/static/index.html
Running this the expectation is
http://localhost:8181/dashboard/index.html shows it.
If using the default context (or WAB) the resources are properly looked
up and you do not call the parent constructor with bundle (and obviously
do not need the whiteboard select).
Your example isn't loading resources with that mechanism (i.e.
getResource being called) you are making the call with the classloader
directly
INI_FILE.load(SampleappShiroFilter.class.getClassLoader().getResourceAsStream("shiro.ini"));
I'm mostly talking another example of this but with a different
whiteboard context:
https://github.com/apache/karaf/tree/main/examples/karaf-http-resource-example
--
Chaz