directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Pierre-Arnaud Marcelot ...@marcelot.net>
Subject Re: [API] Experimenting OSGI fragments to solve the extensibility issue
Date Wed, 19 Oct 2011 21:44:26 GMT
On 19 oct. 2011, at 21:27, Göktürk Gezer wrote:
> On Wed, Oct 19, 2011 at 10:13 PM, Pierre-Arnaud Marcelot <pajbam@gmail.com> wrote:
> Hi Göktürk,
> 
> Le 19 oct. 2011 à 19:05, "Göktürk Gezer" <gokturk.gezer@gmail.com> a écrit
:
> 
>> Hi Pierre,
>> 
>> On Wed, Oct 19, 2011 at 6:36 PM, Pierre-Arnaud Marcelot <pa@marcelot.net> wrote:
>> 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.
>> Hmm, may not be the best, see below. 
>> 
>> 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."
>> Yes, fragments are merged with their host and they left up in the framework as just
resolved, no active state at all. Everything it imports/exports become host's imports/exports.
>> 
>> 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.
>> It would only allow 3th parties to support their own extensions. Why?. Because being
able to classload the 3th party classes is only half of the story. We must also know that
they've arrived and we must know what has been arrived. Otherwise we have to hard code their
name, ant it is not case in 3th party scenario. Once the fragment is merged with the host,
we can class load them inside host and some other bundle having access to that fragments specific
package? But how do we enforce that package names and class names across 3th parties?
> 
> Actually, that's exactly how it works at the moment. The fully qualified name of the
class is available and read from the schema ldif files. That's how we get the other half of
the story. 
> If someone wants to extend the schema with a new comparator, for example, it needs to
provide the class and edit the schema to declare the new comparator. 
> Hmm. yes i see now. Actually this is a problem of Studio more than DS. Because it is
used to create schemas. So when some 3th party provide custom elements, its Studio's responsibility
to find and list it under corresponding GUI element. After that, DS can load it using that
class name either with classloading(with fragments) or OSGI.

Actually what I was describing above has very few to do with Studio. This is the way the schema
is handled in the LDAP API (which is used inside Studio) and within ApacheDS too.

>> 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.
>> Did you do it while knowing the class name on the fragment bundle, or not knowing
the class name at all? 
> 
> Yep, indeed. 
> 
>> 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.
>> Yes it works for us, but for some body writing his own classes, we must dynamically
know they've arrived. 
>>  
>> 
>> 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.
>> It may bring us to somewhere but not even close to real goals IMO. We can use them
to provide in-house extensions, but when it comes to 3th parties, it won't be so easy to use
that fragments comnig from them inside Shared or ApacheDS. 
> 
> Sure, this is some very basic extensibility but it matches perfectly our needs for the
API. On the ApacheDS side, it's another story and we might probably need something better
and more complex. 
> I was already scared to play with shared anyway, now my fear tripled :) But i have some
good news. I made my use of IPojo and OSGI to not broke existing shared clients.

Cool. I'm looking for to seeing that. ;)
Could you share a little bit more how you're doing it?

> But i've got one more issue: the OIDs that's got assigned by constructors, are they static?
or is it possible to lets say BooleanComparator to be instantiated with two different oids.
As I see its not the case and you're maintaining standart OID assigments by hand. What is
the case here?

I guess it's possible to have a BooleanComparator instantiated with two different OIDs, as
soon as the API is open to users (they always manage to find corner cases :)). Especially
in the case where multiple instances are involved. The schema could be very different from
one instance to the other.

Regards,
Pierre-Arnaud

> 
> Regards,
> Pierre-Armaud
> 
>> 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
>> 
>> Regards,
>> Gokturk
> Regards,
> Gokturk


Mime
View raw message