WebContainer not registered

59 views
Skip to first unread message

Pablo Beltran

unread,
May 5, 2021, 4:38:01 PM5/5/21
to OPS4J
Hi,

I'm following this example to register a JSP file.


However, the org.ops4j.pax.web.service.WebContainer service is not initialized.

The initialization of that service happens in the Activator of the Pax-web-Runtime bundle.

In particular, within this method:



protected void updateController(Dictionary<String, ?> dictionary,
ServerControllerFactory controllerFactory)

But the code is a bit weird.

When the bundle is activated and the activator started the method is invoked:

At this time, the local variable initialConfigSet value is false
========
if (!initialConfigSet) {
initialConfigSet = true;
this.config = dictionary;
this.factory = controllerFactory;
dynamicsServiceTracker = new ServiceTracker<>(
bundleContext, ServerControllerFactory.class,
new DynamicsServiceTrackerCustomizer());
dynamicsServiceTracker.open();
return;
=========
}
so, the code inside the block runs, and the method returns.

It seems this method is designed to be invoked twice. But the second call never happens and the code that initializes the WebContainer service is never executed:

===============
httpServiceFactoryReg = bundleContext.registerService(
new String[] { HttpService.class.getName(), WebContainer.class.getName() },
new HttpServiceFactoryImpl() {
@Override
HttpService createService(final Bundle bundle) {
return new HttpServiceProxy(new HttpServiceStarted(
bundle, serverController, serverModel,
servletEventDispatcher, configuration.get(PROPERTY_SHOW_STACKS)));
}
}, props);
==============

In my environment, Eclipse Equinox, PAX web is tied to the Servlet Bridge (HttpService). 

Any idea?

Pablo


Pablo Beltran

unread,
May 5, 2021, 6:57:06 PM5/5/21
to OPS4J
Perhaps this was a wrong approach since the Pax-Web-Extender-War worked (for servlets) with the Servlet Bridge and with the Pax-Web-Runtime not installed. So, the runtime is not required.

On the other hand, the runtime is the bundle responsible for creating the WebContainer service, and this is the problem.

So, it seems I should provide my own WebContainer implementation for JSPs. Is that right? If so, could I reuse the code from the Runtime?

Grzegorz Grzybek

unread,
May 6, 2021, 1:10:24 AM5/6/21
to op...@googlegroups.com
Hello

You did correct analysis - in `if (!initialConfigSet)` block, pax-web-runtime bundle registers a tracker for `ServerControllerFactory.class` OSGi services and there are three bundles that actually register them: pax-web-jetty, pax-web-tomcat and pax-web-undertow.
That's the architecture of Pax Web - it always revolved around reusing real servlet container instead of registering kind of "dispatcher servlet" to single runtime that implemented everything.

if you want JSPs the best way is to simply use entire Pax Web...

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/d59ba9ea-e579-4025-8bdf-7d2938000e8en%40googlegroups.com.

Pablo Beltran

unread,
May 6, 2021, 11:23:05 AM5/6/21
to OPS4J
I randomly chose the Tomcat implementation to figure out how it works and I did some progress, but unfortunately, I stumble with errors. Thought the most critical issue is that it seems to start a new Tomcat Server instance listening to the 8080 (default) port. This is not compatible with the Servlet Bridge since there is already a Tomcat server instance listening to a port (2990 in my particular case).

Then I'll try by using the Jetty implementation as it is based on Jetty 8 which supports nested connections. So my guess is that it will possible to modify the Pax Web sources where the Jetty server is started to do it in nested mode instead and reuse the current HttpServletRequest and HttpServletResponse from the Servlet Bridge without opening any new TCP port.

Grzegorz Grzybek

unread,
May 7, 2021, 1:40:48 AM5/7/21
to op...@googlegroups.com
Hello

To be honest, I've never worked with "Servlet Bridge"... What is it anyway? (I mean what's the github link ;) I know it's kind of mechanism that bridges a WAR into OSGi runtime (probably), where you are not responsible yourself for setting up the servlet container.

Pax Web was always about starting your own server.

There are some Pax Web issues related to "bridge"[1], but I've never touched them.

regards
Grzegorz Grzybek
===

Pablo Beltran

unread,
May 7, 2021, 1:31:22 PM5/7/21
to OPS4J
 The Servlet Bridge has two parts: one runs on the host app (Tomcat/wepapp/lib/servletbridge.jar) which starts OSGi. The other part runs right within OSGi and when the bundle is initialized it registers a ProxyServlet in the host app. Hence, all HttPServletRequest (& HttpServletresponse) received by the Host app (serveltbridge) are forwarded to inside the OSGi Proxy Servlet which is responsible to dispatch the request to the appropriately registered object.

The major difference with starting a Tomcat instance is that the user's request is authenticated with the Servelet bridge.

Please, have a llok at this recorded session (animated gif). It comapres Pax-Web-Extender-War with Eclipse Gemini Web (it claims to be the reference implementation)

NOTES: 
  • The architecture is a Jira instance running on Tomcat and P3 (a plugin for Jira) which runs a pure instance of Equinox under the servlet bridge:
Browser -> Tomcat -> Jira (plugin System) -> P3 (Equinox) -> PAX-Web and Eclipse Gemini Web
  • P3 supports the same Equinox P2 provisionning system as Eclipse to install software, but compiled fro the browser.  So you can install features from any Eclipse repository (Updta Site). In this example Eclipse Gemini Web will be installed from the offcial site.
  • P3 also supports to Apache Felix Web Console to explore the OSGi environment and install and run bundles (for faster development):

pax_web vs gemini.gif

CONSLUSION:
IMHO, Pax-Web works very closesly to Eclipse Gemini Web and Virgo. The big difference is that someone supported (partially at least) the Servlet Bridge in Pax-Web and WABs can run authenticated by reusing the same user's request (session) forwaded by the ServetBridge to the OSGi implementation. And AFAIK Pax-Web is the only implementation able to do it which makes it more enterprise-ready than the rest.

In example, as shown in the recorded session above, Jira plugins (wich are quite complex to develop) can be replaced by standard WAR files converted to WAB bundles ( with the P3 layer to run Equninox and Pax-Web under the the servlet bridge) and published on any third-party Eclipse Repository (Update Site) instead of the official Atlassian Marketplace. This is only a particular example of the power of OSGi and the ability to change the rules.

Hopefully, you found it enough interesting to fix the Web-ContextPath bug in the Pax-Web-Extender-War :)

Pablo.

Grzegorz Grzybek

unread,
May 7, 2021, 2:11:37 PM5/7/21
to op...@googlegroups.com
Thanks for great explanation Pablo!

Hopefully, you found it enough interesting to fix the Web-ContextPath bug in the Pax-Web-Extender-War :)

Looks like I have to read the thread once more on Monday - I didn't yet understand where the problem may be ;)

By the way - I'm almost done with pax-web-extender-war in Pax Web 8 - I've rewritten the context management and how SCIs, fragments, annotated classes are discovered. There are few remaining things about how Whiteboard/HttpService interact with WAB extender, but eventually I'll do it.

regards
Grzegorz Grzybek

Achim Nierbeck

unread,
May 19, 2021, 12:10:31 PM5/19/21
to op...@googlegroups.com
Hi,

I once looked into the servlet bridge thing and decided to leave it where it is ;)
It's kind of strange to think of it this way, you place a OSGi container with a web container inside a web container to call web requests to that inner web container inside a OSGi container.
It's usually easier to just run the war in question inside the Pax-Web (or Karaf) runtime with just a war: url-handler prefix to it.

just shedding some light to why I just never took care of that :)

regards, Achim




--

Apache Member
Apache Karaf <http://karaf.apache.org/> Committer & PMC
OPS4J Pax Web <http://wiki.ops4j.org/display/paxweb/Pax+Web/> Committer & Project Lead
blog <http://notizblog.nierbeck.de/>
Co-Author of Apache Karaf Cookbook <http://bit.ly/1ps9rkS>

Grzegorz Grzybek

unread,
May 20, 2021, 1:32:42 AM5/20/21
to op...@googlegroups.com
Hello

I watched the animated gif few times... Answering to one sentence:

Hopefully, you found it enough interesting to fix the Web-ContextPath bug in the Pax-Web-Extender-War :)

I'm still not sure where's the bug. Web-ContextPath is handled properly by Pax Web - it is used to create relevant backend (jetty, tomcat, undertow) "context" (namely: org.apache.catalina.core.StandardContext, org.apache.catalina.core.StandardContext and io.undertow.servlet.api.DeploymentInfo) with proper context path.

You've shown that if you hit the WAB directly (port 8080) you're not authenticated - that's because the Tomcat instance started by pax-web-tomcat doesn't know about authenticated session managed by the Tomcat (?) instance running on port 2990...

I agree with Achim that:

browser → Servlet container → OSGi Runtime + Servlet Bridge → Pax Web → Servlet Container → WAR/WAB

is a bit strange architecture. Pax Web is an implementation of OSGi CMPN chapters 102, 128 and 140 and puts lots of energy to leverage actual backends (pax-web-jetty, pax-web-tomcat, pax-web-undertow), so you can use (as much as Pax Web allows - mostly in Jetty) use container-specific configurations (Jetty's web-jetty.xml, Tomcat's META-INF/context.xml).

I imagine that Servlet Bridge is kind of wrapper, under which you put another servlet - managed by Pax Web. From my perspective, knowledge and experience, Pax Web explicitly registers HttpService/Whiteboard/WAB servlets into its implementation of HttpService which registers them further (through container-specific ServerController implementation) to actual container runtime. No bridging here.

I've never checked the "bridge" aspects of Pax Web to be honest and when heavily refactoring Pax Web 8, I didn't even see special handling for bridge/wrapper scenarios...

What IS "servlet bridge" in the first place? Is it some Gemino/Virgo bundle?

regards
Grzegorz Grzybek

Reply all
Reply to author
Forward
0 new messages