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]

Reply via email to