On Oct 7, 2009, at 6:51 AM, Rick McGuire wrote:
RFC 66 is an extender that recognizes that OSGi bundles that have a
defined manifest header contain web applications and should be
deployed to a web container. The reference implementation uses an
embedded web container, which is probably not an appropriate
approach for Geronimo, since that would mean Geronimo would be
serving up applications from two different web container instances.
Ideally, a Geronimo-specific version of this extender would have
knowledge of the Geronimo configuration and be capable of deploying
WABs (Web Application Bundles) to the single hosted container, and
ideally would be capable of handling both Tomcat and Jetty
containers as targets.
I started out with the approach of doing a bare-bones implementation
that had nothing that was not required by the RFC 66 draft spec.
WABs are basically standalone web apps, with little or no
integration with the server environment.
Just to clarify, these can have both web.xml and annotations?
And specifically, there's no web services support layered on top of
the WAB. Starting with that assumption, I was able to retask the
code TomcatWebAppContext class to build a context that should allow
a WAB to be deployed to a Tomcat container. The TomcatWebAppContext
is the GBean that gets added to the module configuration by the
TomcatModuleBuilder, and most of the items passed to the constructor
had reasonable defaults I could dummy up. This bit appears fairly
manageable, and I'm sure something similar can be done for Jetty.
However, there are a number of downsides to this approach.
1) No Geronimo or tomcat-specific configuration is supported.
2) No integration with Geronimo security
3) No naming context is provided to the servlet environment.
None of these things are defined or required by RFC 66, but things
like security annotation processing should be supported.
So the next step is to adapt some of the code from the
TomcatModuleBuilder that processes web.xml, geronimo-web.xml, and
geronimo-tomcat.xml and process these files when the context used to
deploy the web application is constructed. At this point, I started
running into some mismatches in how Geronimo deployments are managed
and how RFC 66 deployments need to be managed.
A Geronimo deployment essentially gets converted into a plugin
configuration by unpacking the jar file and creating a plugin
configuration that is then subsequently started. Since processing
is done in two stages, files can be created/altered in the plugin
tree statically, classes can be loaded, etc, all without impact to
the runtime processing of the application.
For a WAB deployment, the extender become involved after the bundle
has been installed and started. At this stage, there's no
opportunity to modify the bundle contents. Additionally, there is
an RFC 66 requirement that if the bundle uses lazy activation, the
bundle should not get activated until the first request for a
servlet instance occurs (i.e., no class loading requests until
deployment).
Going through the TomcatModuleBuilder code, I've found the following
pain points:
1) Creating the initial context naming context for the deployed
application. I'm not really sure what this should be. A lot of
that processing gets delegated to other naming builders, so it's
been a bit difficult to unravel what's really going on here.
You should be able to get environment entries and some resources such
as persistence contexts in the jndi tree without much reference to the
outside world. Datasources and ejbs kind of require some knowledge of
the environment the app is running in. Currently we use the directed
acyclic graph of plugin ancestors to search in for outside-the-app
resources. I think this is a good model but it appears to be
different from what rfc 138 is describing. I don't know how to
resolve this yet.
2) Use of ClassFinder to process the security annotations. The
security configuration is processed by searching for security
annocations on the classes referenced in web.xml. This has the side
effect of forcing classes to be loaded from the bundle, triggering
the early activation.
This doesn't involve loading the application classes, just accessing
their byte code as resources. Does this trigger activation? I
haven't deciphered the lifecycle enough yet to know.
3) What is the Holder used for and how is the instance generated?
This one has been a complete mystery so far, so if anybody can give
an overview of what's going on with that class, it would be most
useful.
This contains the data for injections. It's set up by the naming
builders and annotation framework from the annotations and xml
overrides. (actually the annotation processing generates xml, which is
then processed into the data in the holder).
4) Some of the attributes that are set for the TomcatWebAppContext
are abstract names created as childnames. For a WAB deployment,
these items need to be resolved and located at runtime, rather than
configured as a GBean attribute. Since I don't have a module naming
context to work with at that time, I'm not sure I understand how to
rework this. See line 389 in TomcatModuleBuilder for an example of
the type of query I'm talking about. I think all I need here is an
example for how to convert one of these into a runtime query to get
me unblocked on this.
Those look to me like they are all related to geronimo specific web
app configuration, and I don't see any way to process that without
using the TomcatModuleBuilder. Since it's all optional, I'm not sure
there would be a problem leaving it out.
...
I'm not sure if this would be a significantly different approach to
what you have been considering, but I wonder if this might fit better
with the sandbox osgi framework changes. There I have
ConfigurationActivator that reads the config.ser out of the bundle
into a ConfigurationData and calls some methods on configuration
manager to install it and start stuff up. I wonder if the extender
you are contemplating could call the appropriate deployers to generate
the ConfigurationData directly and then call the same
ConfigurationManager methods. This would probably require some
modification to DeploymentContext which currently constructs a
temporary bundle to load the classes needed by the deployers. Here,
we already have the bundle. I would expect that this kind of approach
would work for any ee app that has been packed into a form that can be
loaded as a bundle: I think this means basically that there is only
one level of jar nesting rather than the 3 levels possible in an ee
app (jar in rar in ear).
hope this helps...
thanks
david jencks
Rick