Will ServletContext OSGi service injections be available in the OSGi 7 compatible web whiteboard

38 views
Skip to first unread message

Steinar Bang

unread,
Feb 11, 2020, 10:43:23 AM2/11/20
to op...@googlegroups.com
I'm currently using shiro 1.5.0 with web whiteboard in karaf 4.2.8.

I'm using some deprecated Shiro classes to set up shiro, and I want to
get rid of using the deprecated classes.

The first snag I've encountered when replacing the deprecated classes is
that the IniWebEnvironment class needs a ServletContext reference, and
that's not something I have.

In the karaf 4.2.8 version of the whiteboard I create a
ServletContextHelper DS component to create the context the servlets and
filters relate to.

But the ServletContextHelper doesn't implement the ServletContext
interface, so I can't use that with the IniWebEnviroment.

Will it be possible to get a ServletContext OSGi service injected into a
@Reference, when using the web whiteboard of OSGi 7?

Grzegorz Grzybek

unread,
Feb 11, 2020, 11:03:13 AM2/11/20
to op...@googlegroups.com
Hello

I'm just in the process of reviewing Pax Web 8.0.0-SNAPSHOT for upcoming Karaf 4.3.0 release. There's lot to review, because some important Whiteboard implementation aspects are not handled correctly in Pax Web (mapping a servlet to multiple ServletContexts for example).

Will it be possible to get a ServletContext OSGi service injected into a
@Reference, when using the web whiteboard of OSGi 7?

Sure - it's described in 128.3.4 Publishing the Servlet Context chapter of CMPN specification and I think it should already be a case (at least that's what I remember from JBoss Fuse (based on Karaf)).

About actual Whiteboard R7 annotations - support for those has yet to be added to Pax Web.

kind regards
Grzegorz Grzybek


--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/86o8u5165h.fsf%40dod.no.

Steinar Bang

unread,
Mar 22, 2020, 7:25:40 PM3/22/20
to op...@googlegroups.com
>>>>> Grzegorz Grzybek <gr.grzybek-Re5JQ...@public.gmane.org>:

>> Will it be possible to get a ServletContext OSGi service injected into a
>> @Reference, when using the web whiteboard of OSGi 7?
>>

> Sure - it's described in 128.3.4 Publishing the Servlet Context chapter of
> CMPN specification and I think it should already be a case (at least that's
> what I remember from JBoss Fuse (based on Karaf)).

Thanks Grzegorz!

I've been successful in injecting the service, but not in filtering to
get the right service.

I got injections in this variant:
@Reference
public void setServletContext(ServletContext context) {
this.context = context;
}

But I got no injections in:
@Reference(target = "(osgi.web.symbolicname=authservice)")
public void setServletContext(ServletContext context) {
this.context = context;
}

And I got no injections in:
@Reference(target = "(osgi.web.contextpath=/authservice)")
public void setServletContext(ServletContext context) {
this.context = context;
}

The ServletContextHelper creating the context, is:
@Component(
property= {
HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME+"=authservice",
HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH+"=/authservice"},
service=ServletContextHelper.class,
immediate=true
)
public class AuthserviceServletContextHelper extends ServletContextHelper { }

> About actual Whiteboard R7 annotations - support for those has yet to be
> added to Pax Web.

Looking forward to this happening.

Thanks again!

Grzegorz Grzybek

unread,
Mar 23, 2020, 2:00:35 AM3/23/20
to op...@googlegroups.com
Hello Steinar Bang

I just checked with pax-web 7 (In Fuse 6) and I could check the service properties of hawtio WAR:

JBossFuse:karaf@root> bundle-services -p 283

io.hawt.hawtio-web provides:
----------------------------------
bundle.id = 283
objectClass = [org.ops4j.pax.web.service.WebAppDependencyHolder]
service.id = 794
----
objectClass = [javax.servlet.ServletContext]
osgi.web.contextpath = /hawtio
osgi.web.symbolicname = io.hawt.hawtio-web
....

As you can see, the properties you're looking for are there. Please check `bundle-services -p` command (or Karaf 4 equivalent) to check what can you filter by. I only now see that Pax Web doesn't properly associate ServletContextHelper services with actual contexts - I'm working on it in Pax Web 8 and I hope to backport some important fixes down to Pax Web 7 later.

regards
Grzegorz Grzybek

--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/86zhc8t1ji.fsf%40dod.no.

Jean-Baptiste Onofré

unread,
Mar 23, 2020, 2:08:12 AM3/23/20
to OPS4J
Hi

AFAIR, those properties are already supported in Pax Web.

Regards
JB

--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/86zhc8t1ji.fsf%40dod.no.

Steinar Bang

unread,
Mar 23, 2020, 1:55:00 PM3/23/20
to op...@googlegroups.com
>>>>> Grzegorz Grzybek <gr.grzybek-Re5JQ...@public.gmane.org>:

> As you can see, the properties you're looking for are there. Please
> check `bundle-services -p` command (or Karaf 4 equivalent) to check
> what can you filter by.

Thanks, Grzegorz!

Yep, the properties are present:

karaf@root()> bundle:services -p 63

Authentication webapp web whiteboard Shiro filter (63) provides:
----------------------------------------------------------------
component.id = 6
component.name = no.priv.bang.authservice.web.security.AuthserviceServletContextHelper
objectClass = [org.osgi.service.http.context.ServletContextHelper]
osgi.http.whiteboard.context.name = authservice
osgi.http.whiteboard.context.path = /authservice
service.bundleid = 63
service.id = 118
service.scope = bundle
----
objectClass = [javax.servlet.ServletContext]
osgi.web.contextname = authservice
osgi.web.contextpath = /authservice
osgi.web.symbolicname = no.priv.bang.authservice.web.security
osgi.web.version = 1.12.0.SNAPSHOT
service.bundleid = 63
service.id = 133
service.scope = singleton
----
component.id = 5
component.name = no.priv.bang.authservice.web.security.AuthserviceServlet
objectClass = [javax.servlet.Servlet]
osgi.http.whiteboard.context.select = (osgi.http.whiteboard.context.name=authservice)
osgi.http.whiteboard.servlet.name = authservice
osgi.http.whiteboard.servlet.pattern = /*
service.bundleid = 63
service.id = 148
service.scope = bundle
karaf@root()>

Hm... so why don't I get service injections when trying to filter on the properties

Steinar Bang

unread,
Mar 23, 2020, 2:21:13 PM3/23/20
to op...@googlegroups.com
>>>>> Steinar Bang <sb-1rLz...@public.gmane.org>:
[snip!]
> objectClass = [javax.servlet.ServletContext]
> osgi.web.contextname = authservice
> osgi.web.contextpath = /authservice
> osgi.web.symbolicname = no.priv.bang.authservice.web.security

> Hm... so why don't I get service injections when trying to filter on the properties

Because I tried the following:
osgi.web.symbolicname=authservice
osgi.web.contextpath=/authservice

It's pretty obvious why osgi.web.symbolicname didn't work. :-)

But osgi.web.contextpath should have worked. Why didn't it work? Did I
fool myself while testing? I think I will try that one again.

osgi.web.contextname sounds like the one I would like to filter on, but
it's not listed here:
https://osgi.org/specification/osgi.cmpn/7.0.0/service.war.html#i3078599

Does that mean that it is deprecated?

Steinar Bang

unread,
Mar 23, 2020, 4:53:26 PM3/23/20
to op...@googlegroups.com
>>>>> Steinar Bang <sb-1rLz...@public.gmane.org>:

> [snip!]
>> objectClass = [javax.servlet.ServletContext]
>> osgi.web.contextname = authservice
>> osgi.web.contextpath = /authservice
>> osgi.web.symbolicname = no.priv.bang.authservice.web.security

>> Hm... so why don't I get service injections when trying to filter on the properties

> Because I tried the following:
> osgi.web.symbolicname=authservice
> osgi.web.contextpath=/authservice

> It's pretty obvious why osgi.web.symbolicname didn't work. :-)

> But osgi.web.contextpath should have worked. Why didn't it work? Did I
> fool myself while testing? I think I will try that one again.

Didn't help.
@Reference(target = "(osgi.web.webcontext=/authservice)")
doesn't match.

A breakpoint in the setter is never triggered and the bundle is never
activated (since the reference isn't satisfied).

Steinar Bang

unread,
Mar 23, 2020, 5:34:12 PM3/23/20
to op...@googlegroups.com
I started thinking maybe it was the leading / on the match value that
was the problem? Maybe the / has special significance for the LDAP
syntax? Maybe the match has to start with an alphanumeric character...?
Or something...?

So I tried
@Reference(target = "(osgi.web.contextname=authservice)")
and that worked just fine: the setter was called and the @Activate
method was called and the bundle became active.

The problem with using this was that osgi.web.contextname wasn't in the
list of properties mentioned in what I assume will be the next
generation of the web web whiteboard.

So what to do?

Presumably
@Reference(target = "(osgi.web.symbolicname=no.priv.bang.authservice.web.security)")
will also work, but I don't like it (it's long, cluttered and sort of
misleading)

Grzegorz Grzybek

unread,
Mar 24, 2020, 4:52:26 AM3/24/20
to op...@googlegroups.com
Hello

So I tried
    @Reference(target = "(osgi.web.contextname=authservice)")
and that worked just fine: the setter was called and the @Activate
method was called and the bundle became active.

I just checked what pax web is doing and it's:

properties.put(WebContainerConstants.PROPERTY_SERVLETCONTEXT_NAME, context.getServletContext().getServletContextName());

PROPERTY_SERVLETCONTEXT_NAME == "osgi.web.contextname"

I just checked specification 128.3.4 Publishing the Servlet Context (OSGi CMPN) and there's only "osgi.web.contextpath" property, no "osgi.web.contextname"...

I'll review in Pax Web 8, but for now, you have the answer. If Pax Web registered not:

context.getServletContext().getServletContextName();

but

context.getServletContext().getContextPath();

you'd have the path. Now you have the name, so your @Reference(target = "(osgi.web.contextname=authservice)") should work.

regards
Grzegorz Grzybek

--
--
------------------
OPS4J - http://www.ops4j.org - op...@googlegroups.com

---
You received this message because you are subscribed to the Google Groups "OPS4J" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ops4j+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ops4j/86ftdyu566.fsf%40dod.no.

Steinar Bang

unread,
Apr 2, 2020, 11:49:52 AM4/2/20
to op...@googlegroups.com
Injection of ServletContext worked (as can be seen earlier in this
thread).

But it turns out it wasn't needed because the Shiro AbstractFilter class[1]
extends ServletContextSupport[2], and saves the ServletContext when
receiving the FilterConfig[3].

So shiro filters already have the ServletContext (and automatically get
the right one).

References:
[1] <https://github.com/apache/shiro/blob/master/web/src/main/java/org/apache/shiro/web/servlet/AbstractFilter.java#L38>
[2] <https://github.com/apache/shiro/blob/master/web/src/main/java/org/apache/shiro/web/servlet/ServletContextSupport.java#L28>
[3] <https://github.com/apache/shiro/blob/master/web/src/main/java/org/apache/shiro/web/servlet/AbstractFilter.java#L66>
Reply all
Reply to author
Forward
0 new messages