Hi Dev,

Following our efforts on the OSGI side, I took some time to think about (and 
experiment) how we could solve our extensibility issue on the LDAP API, where 
we want our users to be able to provide their own custom implementation of 
various schema objects like comparators, normalizers, etc.

After a quick discussion with Emmanuel and Guillaume Nodet, it turned out using 
OSGI fragments bundles could probably be our best solution.

Here's a definition of what an OSGI fragment bundle is (more information 
available at [1]):
"An OSGi fragment is a Java archive file with specific manifest headers that 
enable it to attach to a specified host bundle or specified host bundles in 
order to function.
Fragments are treated as part of the host bundles. Relevant definitions of the 
fragment are merged with the host bundles definitions before the host is 
resolved, as long as the information does not conflict.
Fragment dependencies are resolved if possible. If the fragment dependencies 
can not be resolved, the fragment does not attach to the host bundle.
A fragment can not have its own class loader or bundle activator. It can not 
override the information present in the host bundles. Fragments extend bundles 
with resources, classes, and permitted headers enabling you to customize your 
bundles."

The great thing about fragments is that they *share* the same class loader as 
their host bundle. Which was pretty much the kind of issue we were having with 
classloaders being differents from one bundle to the other.

The other great thing I see with this approach, it that it would also work 
great outside of an OSGI container application (which is a strong requirement 
for the LDAP API). A fragment bundle is nothing else than a regular bundle with 
a specific OSGI directive (Fragment-Host) added to its MANIFEST.MF file, and a 
bundle behaves exactly like a plain jar file when it's not included in an OSGI 
container. Thus, it would allow us to support third parties extensions.

I have done a small experiment in my Eclipse workspace with two bundles (one 
being the host and the other being the fragment ) and I was able to classload, 
without any classloader issue, a class defined in the fragment bundle from 
another class inside the host bundle.

I'd like to go a step further and experiment this on the API itself.

Ideally, I'd like to use the 'shared-ldap-model' module 
('org.apache.directory.shared.ldap.model' bundle) as a host for all our schema 
objects implementations and move these implementations into a specific fragment 
bundle containing them all.
Users would have to do the same to include their extensions. A simple fragment 
bundle with the 'org.apache.directory.shared.ldap.model' bundle as host and it 
works.

One other thing that should be done, is to let the 'shared-ldap-model' module 
do the instanciation of the schema elements. At the moment, two classes from 
the 'shared-ldap-schema-data' module are responsible for this, 
'org.apache.directory.shared.ldap.schemaloader.SchemaEntityFactory' and 
'org.apache.directory.shared.ldap.schemaloader.AttributeClassLoader'. We would 
need to move these classes to the 'shared-ldap-model' module, for them to have 
access to the right class loader.

All in all, I think that's the only things we need to do to get the 
extensibility we wanted inside and outside an OSGI container.

What do you think of this plan?

Regards,
Pierre-Arnaud

[1] - 
http://publib.boulder.ibm.com/infocenter/radhelp/v8/index.jsp?topic=/com.ibm.osgi.common.doc/topics/cbundlefragment.html

Reply via email to