Regarding HttpService - I don't think it's a good idea for tomcat.
One of the major problems with OSGI ( and we need to make sure we
don't fall
in this trap ) is the re-invention of common APIs - logging, servlet
interfaces, etc.
As a bit of background. The logging and Http Service API are from
1999. At that time
there was no dominant common logging API (neither in Java SE nor in
open source),
and the Http Service API is 100% based on the, at that time, standard
Servlet API (it
uses javax.servlet.http), it only provides an API to dynamically
register and unregister
servlets, which is still lacking in the current Servlet API. On top of
that, all these service APIs are optional. If you look in more detail,
than many services are
similar: providing a possibility to -dynamically- use Java APIs. I.e.
XML parsers, IO Connectors
(J2ME), Servlets, URL stream and content handlers, Preferences, etc.
We are not looking for
work and try to leverage the existing Java environment to the utmost
extent.
This said, I agree that you want the core of a product like Tomcat to
be as decoupled
as possible of any frameworks, including OSGi. Decoupling is the
guiding principle behind
OSGi and the raison d'etre for most of its functionality. Not using a
service is better than
coupling to it. But sometimes not using a service is more expensive
than using it, that
decision is what design is all about.
It would be quite inappropriate for tomcat to not use the standard
deployment/configuration mechanism for
servlets. So using or implementing any of the OSGI-re-defined
service interfaces in
tomcat would be a hard sale IMO.
Well, I do not see that this is an dichotomy. By nature of being the
RI, you must follow the
JSR. However, it would not be hard to provide the Http Service as an
additional component. If
Tomcat provides an API to dynamically register servlets, it would be
trivial for someone
to provide an OSGi compatibility bundle, just like people are doing it
today.
But it would be a nice service to get this from the horse's mouth. I
am sure people are willing
to provide this code.
A bit more background. 4 years ago IBM started to like the OSGi
modularity (class loaders on
steroids) and the silly, unnecessary life cycle and service layer.
Actually, we had no visible
layers back then. At that time, there were raging debates about
modularity with lots of
competition. This was actually the trigger for R4 to put the 4 layers
into place: security, execution
environment, modularity, life cycle, service. Key idea was that people
could pick the modularity
layer without dragging in the life cycle and service layer. I think
the dislike for these
layers was based on lack of familiarity because what happened was that
people started to
use the modularity, then found out how convenient the life cycle layer
is in development. You
can keep your app server running while debugging and updating code.
However, getting hooked to the life cycle layer (if only for
development) means things are
coming and going. Coupling through the module layer (i.e. factories,
Class.forName, etc) means
you create import wires to other modules that can not be dynamically
withdrawn because Java lacks an API for
this. In OSGi, it is not a big deal because you can still stop a
bundle, update it, and refresh all the
import wires. This is feasible because bundles can be started and
stopped and the OSGi framework
is intricately aware of these import wires.
In reality, this is a rather crude approach because in well designed
systems the coupling between bundles
is minimal. At this point in time, services usually start to look more
attractive because they provide
an API to allow dynamic updates without crudely stopping all bundles
in the module dependency
graph (which in non-service based systems, and especially require-
bundle based systems tends
to become the whole system). And a service is just a POJO that is
registered under one or more interfaces. By allowing
it to withdrawn at any moment in time, as well as registered by
multiple independent parties, OSGi
provides a good abstraction of this dynamism. And there is no Java
counterpart for this.
With JSR 291 we had the same situation. There was a requirement to get
rid of the service layer
because it was deemed unnecessary. We puzzled with the interfaces in
OSGi so that we
could be backward compatible and still have this separation. We got
some solution but it
felt awkward. Worse, there are a number of optional APIs in the OSGi
framework to manage
the modularity layer (PackageAdmin), the security (PermissionAdmin and
ConditionalPermissionAdmin),
startlevels, and URL stream and content handling. By removing the
service layer we had to
find an alternative way to provide these APIs to the bundles.
Factories? Dependency Injection?
Class.forName? They all felt far inferior to the service model, all
lacking the dynamics. We then
looked at the API, only 4 specific classes and 3 methods on the core
framework interface class
BundleContext. The implementations were around 30-40k so in the end we
decided to keep the
service layer around in JSR 291 because there was no decent
alternative, the functionality
was needed, and 50k seems a low price to pay.
Last illustration and then I shut up. 2 years ago we were approached
by Spring. Customers had told them that OSGi was
cool. Spring is in the business of providing convenience APIs to
complex core APIs and they approached
this job in that vein. OSGi, just one of the zillion environments that
had to be supported
by the Spring suite. However, something very interesting happened over
the next few months. I think
they fell in love and the service layer was a major part of their
infatuation. They
realized very quickly how they could leverage the services as beans in
their model and the
advantages of dynamism without rebooting.
Is there a way for a bundle to declare that it implements some
services
using manifest or some config file, but without requiring it to be
started to register
services via BundleContext ? What I would like is to start tomcat,
use server.xml
to find what services are needed, and load the bundles providing the
modules
( and only those ).
This is the use case of Declarative Services. The Service Component
Runtime (SCR)
will inspect the bundle when it gets installed and register any
services that
are declared and which have their dependencies on other services
satisfied.
The bundles themselves are not having a classloader, nor started. Only
when the
service is really used by another bundle will the bundle be activated
by the
SCR. If the dependencies go away, the component is deactivated. This
is of course
all runtime based.
There is also OBR (Apache Felix's Richard Hall is the key author of
this) which is the
OSGi Bundle Repository. This is a model where you can install bundle
X, and then
OBR can install any dependent bundles. The dependency model is very
flexible (an extension
to JSR 124) which also supports dependencies on services. However,
realize that the dynamic
nature means that there never is a guarantee a service is registered
by a bundle, even
if it is started because some dependency can be missing, or a bundle
can be updated, etc.
The OSGi manifest does have a header Export-Service and Import-Service
defined but because
you can't give an guarantees about them without running the bundle, we
decided to deprecate them.
However, how much do you want to be in the business of deployment?
Tomcat is very often used
as an application server but the web site tells me your core is a
Servlet and
JSP implementation. If you are going for strict modularity, wouldn't
it make sense to distinguish
between these core functions; Aren't the application management
aspects secondary? I.e.
allow your core JSP and Servlet engines to be used by others that
provide the deployment
aspects and allow your deployment code to be able to use other web
service providers? How
can you leverage existing deployment servers and management agents?
For me the key thing about
modularity is to do as little as possible and focus on core business.
Sorry for the rather verbose mail, I did not have enough time to write
a short one. :-(
Kind regards,
Peter Kriens
On 29 apr 2008, at 19:48, Costin Manolache wrote:
On Mon, Apr 28, 2008 at 11:25 PM, Peter Kriens
<[EMAIL PROTECTED]>
wrote:
Tomcat to really make a lot of sense. Providing OSGi headers seems to
fulfill
the immediate need of several groups. However, it would be really
nice if
you
could provide a service interface like an Http Service (Http Service
itself
is Servlet 2.1,
so you likely need something better). However, if you put the
headers in
Headers seems to be ok - I don't think anyone objected to this.
Regarding HttpService - I don't think it's a good idea for tomcat.
One of the major problems with OSGI ( and we need to make sure we
don't fall
in this trap )
is the re-invention of common APIs - logging, servlet interfaces,
etc. It
would be quite inappropriate
for tomcat to not use the standard deployment/configuration
mechanism for
servlets.
So using or implementing any of the OSGI-re-defined service
interfaces in
tomcat would be a hard sale IMO.
I think the more ambitious case then is to leverage the OSGi class
loading
and
allow WARs to be installed dynamically. Several people (there is
also an
There are 3 issues here:
- dynamic installation and uninstallation of WARs - that's already
working
quite well, no need for OSGI.
- 'gapless' upgrade (old version running alongside with the new
one)- OSGI
has no magic bullet for that, the problem
is more in the mapping layer.
- using OSGI class loading to allow more flexible interaction
between WARs.
Unfortunately that is invalidated by
the servlet spec, which clearly defines this area.
Of course then there is the possibility to turn Tomcat itself into
separate
bundles and
leverage OSGi internally. This is an interesting exercise but
looking at
the sentiments
in this list I think this is a far way off :-)
Quite the opposite, I think this would be the best use of OSGI - if
we can
avoid the bad things in OSGI ( like the
service APIs and over-use of bundle activator and service
registration ).
What tomcat needs the most IMO is a way to separate 'core'
functionality
from 'modules' - like
authenticators, session management, connectors. Using OSGI bundles for
modules and integrating
with the lifecycle would be ok if it can be done non-intrusive:
- some OSGI-independent interface ( with a OSGI implementation and a
'direct' one ) to load the module.
I personally like JBoss style of modules as well - so that could be
a 3rd
implementation ( maybe outside of apache ).
- some code loaded from server.xml that would start the OSGI
container and
load the modules
- use OSGI/Jboss-style class loader to allow the modules and core to
share
classes.
Most of this can be done in an 'optional' package ( i.e. in the
trunk, but
not included in the 'official' base release ).
Few simple interfaces and impl changes may need to be added to the
core -
but it can be very light.
In OSGi, the bundles are first class citizens in the API. This
allows an
extender bundle to read resources from the bundle when it gets
started
and
take appropriate actions. I.e. a WAR manager bundle can detect
reliably
the
installation of new bundles, read the appropriate XML files, and do
the
registrations. So the "non standard" method would be internal
Tomcat API
called by a Tomcat bundle. I think it is a very good requirement to
keep
the
WAR the WAR and not require any OSGi code in there. In the longer run
OSGi could update the rather stale Http Service specification to
add this
kind of management API, allowing the WAR manager and the web server
to be
independent bundles so that developers can mix and match.
I'm pretty sure most people want to use OSGi for services, and
Servlet API
for web development. HttpService is a non-starter - it would be
great if the next servlet API
defines interfaces for dynamic (code-based) loading of servlets -
and we can provide some
tomcat-specific interfaces ( like jetty does ) - but OSGi is not
the right place to look
for servlet ( or logging ) APIs.
My main question regarding OSGI bundles and services:
Is there a way for a bundle to declare that it implements some
services
using manifest or some config file, but without
requiring it to be started to register services via BundleContext ?
What I
would like is to start tomcat, use server.xml
to find what services are needed, and load the bundles providing the
modules
( and only those ).
Costin
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]