Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Rich Client Platform (RCP) » Plugins vs. Fragments
Plugins vs. Fragments [message #452588] Sun, 09 July 2006 22:32 Go to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
Hi,

I just began considering Fragments for my project, for a simple reason:

I needed a way to have a library on the exact same classpath as the plugin
using it. This is a scenario where Buddy-Classloading or other Classloader
hacks actually dont work.

I was impressed how easy to setup a Fragment. Everything is working fine.
There is no classpath issue.

Now I am curious: Why do people ask for Buddy-Class-Loading, if this problem
can easily be solved using Fragments? Is there anything that limits a Fragment
compared to a Plugin? The only limit I can see is that Fragments don't have
an Activator class. But they can still use Extension-Points and participate
in contributions.

Ben
Re: Plugins vs. Fragments [message #452594 is a reply to message #452588] Mon, 10 July 2006 14:07 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Benjamin Pasero wrote:

> Hi,
>
> I just began considering Fragments for my project, for a simple reason:
>
> I needed a way to have a library on the exact same classpath as the plugin
> using it. This is a scenario where Buddy-Classloading or other Classloader
> hacks actually dont work.
>

I'm sure those hacks will work. You probably don't understand them well
enough or don't like _how_ they work.

> I was impressed how easy to setup a Fragment. Everything is working fine.
> There is no classpath issue.
>

I used to use fragments like this as well. In the end you will find they
are not "supported." They are only supported for their Eclipse-esque
useage which is adding on language packs. If you try to use them for their
ability to get into the classpath you will eventually find bugs. In fact
using them this way will make you the #1 bug finder for this use because
nobody in Eclipse seems to test this usage. No big deal. Plus this is
what open source is about. I stopped using fragments like this after a few
years because after each upgrade I got tired of being the one to find the
bugs. Actually I enjoyed finding the bugs and the team fixed them fast.
It just became clear that this would be an issue ongoing.

> Now I am curious: Why do people ask for Buddy-Class-Loading, if this
> problem can easily be solved using Fragments? Is there anything that
> limits a Fragment compared to a Plugin? The only limit I can see is that
> Fragments don't have an Activator class. But they can still use
> Extension-Points and participate in contributions.
>
> Ben

A fragment can only 'frag' a single plugin. A plugin can be loaded or used
by multiple plugins. People generally do not ask for Buddy loading.
Generally, they come to the newsgroup with a question about their secondary
library not acting right, and everyone offers up buddy loading as the
solution. I think this is the wrong solution and expressed that opinion
when it was being developed. But it works and sometimes working is all
that people care about.

My advice is to isolate plugins from external dependencies as much as
possible. A plugin should be responsible for its own classes and not need
help loading anything. Looks like a dependency mess to me.



--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452595 is a reply to message #452588] Mon, 10 July 2006 14:07 Go to previous messageGo to next message
Alex Blewitt is currently offline Alex BlewittFriend
Messages: 946
Registered: July 2009
Senior Member
They're really solving two different problems. One is getting classes in a bundle to load classes from a dependent bundle (which would otherwise cause circular dependencies). The other is about patching existing classes in a bundle.

If the library is expected to be used by several different bundles, then having a standalone bundle makes a lot of sense, since it can be reused. Most of the problems can be fixed with buddy classloading. If you're injecting a library via a fragment, then that library is specific to that bundle (and there's really no difference with putting the library directly in the bundle itself).

The only time you're likely to notice a difference is when you have a need to share that library across two (or more) bundles; using a fragment, you'll just end up duplicating the library, but in a separate bundle, you'll end up sharing the library.

Fragments can't exist outside the scope of a plugin; so they need to live in a symbiotic relationship with a plugin/bundle. Furthermore, you can't have extension points exported by a fragment that is then visible to dependent bundles -- they're only visible to the plugin that they're feeding off.

In any case, when using libraries like hibernate or log4j, the idea is that they'll be reusable and so you don't want to contribute them each time.

(On a side-note; why bother contributing the library as a fragment at all, when you can just include that library in the bundle?)

Alex.
Re: Plugins vs. Fragments [message #452597 is a reply to message #452595] Mon, 10 July 2006 14:23 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Alex Blewitt wrote:

> They're really solving two different problems. One is getting classes in a
> bundle to load classes from a dependent bundle (which would otherwise
> cause circular dependencies). The other is about patching existing classes
> in a bundle.
>

This is still a circular dependency.

> If the library is expected to be used by several different bundles, then
> having a standalone bundle makes a lot of sense, since it can be reused.
> Most of the problems can be fixed with buddy classloading. If you're
> injecting a library via a fragment, then that library is specific to that
> bundle (and there's really no difference with putting the library directly
> in the bundle itself).
>

The fragment does not have to be present. You could have a mysql fragment
and a postgres fragment. The user can choose which db he/she wants. When
a new db is supported the developer releases a new fragment.


--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452626 is a reply to message #452594] Mon, 10 July 2006 20:06 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
CL [dnoyeb] Gilbert wrote:
> Benjamin Pasero wrote:
>
>> Hi,
>>
>> I just began considering Fragments for my project, for a simple reason:
>>
>> I needed a way to have a library on the exact same classpath as the plugin
>> using it. This is a scenario where Buddy-Classloading or other Classloader
>> hacks actually dont work.
>>
>
> I'm sure those hacks will work. You probably don't understand them well
> enough or don't like _how_ they work.

You are right, I was a bit too fast making this statement. Playing around
with BuddyLoading, I am now able to workaround my issue using it.

>
>> I was impressed how easy to setup a Fragment. Everything is working fine.
>> There is no classpath issue.
>>
>
> I used to use fragments like this as well. In the end you will find they
> are not "supported." They are only supported for their Eclipse-esque
> useage which is adding on language packs. If you try to use them for their
> ability to get into the classpath you will eventually find bugs. In fact
> using them this way will make you the #1 bug finder for this use because
> nobody in Eclipse seems to test this usage. No big deal. Plus this is
> what open source is about. I stopped using fragments like this after a few
> years because after each upgrade I got tired of being the one to find the
> bugs. Actually I enjoyed finding the bugs and the team fixed them fast.
> It just became clear that this would be an issue ongoing.

I had expected something like that. However, its really not just used for
language packs. Its used to patch SWT with the native library, and some other
platform dependant stuff in various fragments is existing too.

However, given that Buddy-Classloading is somewhat unpublic, non-final "API",
I am not sure wether its better to use these over Fragments?

>
>> Now I am curious: Why do people ask for Buddy-Class-Loading, if this
>> problem can easily be solved using Fragments? Is there anything that
>> limits a Fragment compared to a Plugin? The only limit I can see is that
>> Fragments don't have an Activator class. But they can still use
>> Extension-Points and participate in contributions.
>>
>> Ben
>
> A fragment can only 'frag' a single plugin. A plugin can be loaded or used
> by multiple plugins. People generally do not ask for Buddy loading.
> Generally, they come to the newsgroup with a question about their secondary
> library not acting right, and everyone offers up buddy loading as the
> solution. I think this is the wrong solution and expressed that opinion
> when it was being developed. But it works and sometimes working is all
> that people care about.

Right

>
> My advice is to isolate plugins from external dependencies as much as
> possible. A plugin should be responsible for its own classes and not need
> help loading anything. Looks like a dependency mess to me.
>
>
>
Re: Plugins vs. Fragments [message #452627 is a reply to message #452595] Mon, 10 July 2006 20:11 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
Alex Blewitt wrote:
> They're really solving two different problems. One is getting classes in a bundle to load classes from a dependent bundle (which would otherwise cause circular dependencies). The other is about patching existing classes in a bundle.
>
> If the library is expected to be used by several different bundles, then having a standalone bundle makes a lot of sense, since it can be reused. Most of the problems can be fixed with buddy classloading. If you're injecting a library via a fragment, then that library is specific to that bundle (and there's really no difference with putting the library directly in the bundle itself).
>
> The only time you're likely to notice a difference is when you have a need to share that library across two (or more) bundles; using a fragment, you'll just end up duplicating the library, but in a separate bundle, you'll end up sharing the library.
>
> Fragments can't exist outside the scope of a plugin; so they need to live in a symbiotic relationship with a plugin/bundle. Furthermore, you can't have extension points exported by a fragment that is then visible to dependent bundles -- they're only visible to the plugin that they're feeding off.
>
> In any case, when using libraries like hibernate or log4j, the idea is that they'll be reusable and so you don't want to contribute them each time.
>
> (On a side-note; why bother contributing the library as a fragment at all, when you can just include that library in the bundle?)
>
> Alex.

This is all about extensibility. If I was to integrate the JDBC Driver into my
Model-Plugin, I would lose flexibility in terms of extensibility. My goal is to
let others decide which driver to use. Thats why I find it often the best
solution to seperate libraries from the plugins they are used in. I see two
advantages:

1.) As for a JDBC Driver, its replaceable. Others might want to use their
Database and replace the Plugin with their plugin.

2.) The library is most likely updated in a different interval compared to
my own code. Updating a library would require to re-ship the entire plugin. In a
seperate library-plugin I am able to just update the library and keep my
Model-Plugin as is.

Ben
Re: Plugins vs. Fragments [message #452631 is a reply to message #452627] Mon, 10 July 2006 21:25 Go to previous messageGo to next message
Alex Blewitt is currently offline Alex BlewittFriend
Messages: 946
Registered: July 2009
Senior Member
> 1.) As for a JDBC Driver, its replaceable. Others might want to use their
> Database and replace the Plugin with their plugin.

You can do the same thing with extension points and buddy class-loading. Your code can have a 'driver' registration, which iterates through all provided extension providers, and the JDBC driver can contribute to an extension point e.g.

<driver class="org.foo.JDBCDriver" options="xxxx'/>


As long as buddy class-loading is enabled, your master plugin will be able to see all the drivers provided based on which bundles are started. It's a bit more work, though.

> 2.) The library is most likely updated in a different interval compared to
> my own code. Updating a library would require to re-ship the entire plugin. In a
> seperate library-plugin I am able to just update the library and keep my
> Model-Plugin as is.

That's usually why people ahve a separate library plugin :-) The problem with a fragment approach is that it's specific to the plugin it's contributing to -- so an applciation may host many copies of the same driver code, for each plugin that uses it. At least using a separate plugin, you can update that individually.

Anyway, sounds like you sorted your problem out anyway.

Alex.
Re: Plugins vs. Fragments [message #452634 is a reply to message #452631] Tue, 11 July 2006 06:03 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
Alex Blewitt wrote:
>> 1.) As for a JDBC Driver, its replaceable. Others might want to use their
>> Database and replace the Plugin with their plugin.
>
> You can do the same thing with extension points and buddy class-loading. Your code can have a 'driver' registration, which iterates through all provided extension providers, and the JDBC driver can contribute to an extension point e.g.
>
>
> <driver class="org.foo.JDBCDriver" options="xxxx'/>
> 

>
> As long as buddy class-loading is enabled, your master plugin will be able to see all the drivers provided based on which bundles are started. It's a bit more work, though.
>

Yep, thats the approach I am currently using. I need to use extension-points
anyways, because each JDBC Driver has its own Class that needs to be loaded.
Simply having a DB Plugin seperate, does not automatically make JPA use it.

>> 2.) The library is most likely updated in a different interval compared to
>> my own code. Updating a library would require to re-ship the entire plugin. In a
>> seperate library-plugin I am able to just update the library and keep my
>> Model-Plugin as is.
>
> That's usually why people ahve a separate library plugin :-) The problem with a fragment approach is that it's specific to the plugin it's contributing to -- so an applciation may host many copies of the same driver code, for each plugin that uses it. At least using a separate plugin, you can update that individually.
>
> Anyway, sounds like you sorted your problem out anyway.

Actually even with using Fragments its possible for others to use it too,
as long as they have a dependancy to the host plugin. Of course its not
very obvious for others, that this library is existing.

Btw, the Eclipse RCP Book tells, that Buddy-Classloading should really only
be used as last solution, due to some issues. One issue stated is performance-
considerations. For a Plugin to lookup classes from Buddies is not for free.

I think in a scenario where a Plugin's content really only means something to
one plugin (as in my situation), using Fragments is ok. I dont need other
plugins to use any package from the Fragment too.

Ben

>
> Alex.
Re: Plugins vs. Fragments [message #452646 is a reply to message #452631] Tue, 11 July 2006 13:16 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Alex Blewitt wrote:

>> 1.) As for a JDBC Driver, its replaceable. Others might want to use their
>> Database and replace the Plugin with their plugin.
>
> You can do the same thing with extension points and buddy class-loading.
> Your code can have a 'driver' registration, which iterates through all
> provided extension providers, and the JDBC driver can contribute to an
> extension point e.g.
>

You can do the same thing with extension points and no buddy class-loading.
That is how I have 1 plugin to support JDBC and one to support JDO and one
planned to support Hibernate.


>
> <driver class="org.foo.JDBCDriver" options="xxxx'/>
> 

>
> As long as buddy class-loading is enabled, your master plugin will be able
> to see all the drivers provided based on which bundles are started. It's a
> bit more work, though.
>

You can do this by using simple tokens to explain which plugin the
particular project is associated with. And if you are not doing
serialization you dont even need this much.


>> 2.) The library is most likely updated in a different interval compared
>> to my own code. Updating a library would require to re-ship the entire
>> plugin. In a seperate library-plugin I am able to just update the library
>> and keep my Model-Plugin as is.
>
> That's usually why people ahve a separate library plugin :-) The problem
> with a fragment approach is that it's specific to the plugin it's
> contributing to -- so an applciation may host many copies of the same
> driver code, for each plugin that uses it. At least using a separate
> plugin, you can update that individually.
>
> Anyway, sounds like you sorted your problem out anyway.
>
> Alex.

Actually fragments work just as well as plugins here. Its just the bugs you
find over time. I use plugins now because they are less buggy, but no
other reason besides that.



--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452760 is a reply to message #452588] Thu, 13 July 2006 23:21 Go to previous messageGo to next message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
Benjamin,

There is a very important use case where Buddy classloading (or
DynamicImport-Package, which I prefer) is needed. The rule is essentially
this: if a bundle does any form of Reflection or dynamic runtime
classloading, it needs to use Buddy/DynamicImport.

The canonical example is a Hibernate bundle. Say you are using Hibernate
to map a database table to your Customer class. The Customer class sits in
package com.my.domain in the "domain" bundle. In order to produce
instances of customer, Hibernate must dynamically access the class (using
Class.forName() or similar) and instantiate it.

Now you can't just make your Hibernate bundle depend on your domain
bundle, either through Import-Package or Require-Bundle. Hibernate is a
generic service, it should not have a design time dependency on your
specific domain. You don't know what other domains Hibernate might be used
with later, and anyway this would create a cyclical dependency.

Neither can you make your domain bundle into a fragment of the Hibernate
bundle, because that would tightly couple you to the Hibernate bundle. Eg
you could not deliver your domain without Hibernate coming along too. Also
a fragment can only be hosted by a single bundle, so if you have any other
reflection intensive bundles (eg Spring) then you would have to create a
whole separate fragment.

It should be obvious therefore that your domain needs to be a fully
fledged bundle, rather than a fragment. Fragments should really only be
used for three things:

1) Localization files
2) Platform-specific code
3) Unit test code (because the tests in the fragment have full access to
the classes in the host bundle, even the non-exported packages)

Given then that your domain needs to be in a bundle, you really do need to
use something like buddy loading. In fact I recommend you use
"DynamicImport-Package: *" instead of buddy loading, since it is a
standard OSGi mechanism (whereas buddy loading is specific to Eclipse) and
in my experience less error prone. It's also very simple to understand: if
I declare the Hibernate bundle with "DynamicImport-Package: *" then when
Hibernate attempts to load the com.my.domain.Customer class, the
classloader will search for a com.my.domain package being exported by ANY
bundle. Note that DynamicImport respects the encapsulation of bundles - it
will never allow another bundle to load from the non-exported packages of
a bundle.

Unfortunately both buddy loading and DynamicImport do also allow you to
make cyclical dependencies. As with many things they can be used for both
good and evil.

- Neil


Benjamin Pasero wrote:

> Hi,

> I just began considering Fragments for my project, for a simple reason:

> I needed a way to have a library on the exact same classpath as the plugin
> using it. This is a scenario where Buddy-Classloading or other Classloader
> hacks actually dont work.

> I was impressed how easy to setup a Fragment. Everything is working fine.
> There is no classpath issue.

> Now I am curious: Why do people ask for Buddy-Class-Loading, if this problem
> can easily be solved using Fragments? Is there anything that limits a
Fragment
> compared to a Plugin? The only limit I can see is that Fragments don't have
> an Activator class. But they can still use Extension-Points and participate
> in contributions.

> Ben
Re: Plugins vs. Fragments [message #452775 is a reply to message #452760] Fri, 14 July 2006 08:42 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
Neil Bartlett wrote:
> Benjamin,

Hi Neil,

interesting, I never heard of DynamicImport before. I will give it
a try. While I am able to use Buddy-Classloading to get the Database
work with Oracly Toplink, I am unable to seperate Toplink from my
Domain, even with Buddy-Classloading. Toplink expects an XML file
being on the classpath, where it reads persistence settings. Somehow
Buddy-Classloading did not work in that area.

I agree that the domain-plugin should not be dependant on the JPA
(or as in your example Hibernate) plugin. Currently its the other
way around: The JPA (Library) Plugin is a Fragment with the domain-
plugin as Host:

org.mydomain: Plugin containing Model that is to be persisted
org.jpa: Fragment containing JPA library. Host is org.mydomain
org.db: Fragment containing DB-JDBC-Library. Host is org.mydomain

(org.db can either be a Fragment or a Plugin. As mentioned, I was able
to use Buddy-Classloading in that area).

As you can see, all these libraries are actually tightly coupled to
the domain-plugin. There is no requirement to use them outside the
model (e.g. as a Library for other services).

If someone is going to extend my model, he depends on my Model anyways
and will get JPA as a dependancy automatically (by using ExportApis:true).


Anyways, I am giving DynamicImport a try, since I feel better using real
plugins.

Ben

>
> There is a very important use case where Buddy classloading (or
> DynamicImport-Package, which I prefer) is needed. The rule is
> essentially this: if a bundle does any form of Reflection or dynamic
> runtime classloading, it needs to use Buddy/DynamicImport.
>
> The canonical example is a Hibernate bundle. Say you are using Hibernate
> to map a database table to your Customer class. The Customer class sits
> in package com.my.domain in the "domain" bundle. In order to produce
> instances of customer, Hibernate must dynamically access the class
> (using Class.forName() or similar) and instantiate it.
>
> Now you can't just make your Hibernate bundle depend on your domain
> bundle, either through Import-Package or Require-Bundle. Hibernate is a
> generic service, it should not have a design time dependency on your
> specific domain. You don't know what other domains Hibernate might be
> used with later, and anyway this would create a cyclical dependency.
>
> Neither can you make your domain bundle into a fragment of the Hibernate
> bundle, because that would tightly couple you to the Hibernate bundle.
> Eg you could not deliver your domain without Hibernate coming along too.
> Also a fragment can only be hosted by a single bundle, so if you have
> any other reflection intensive bundles (eg Spring) then you would have
> to create a whole separate fragment.
>
> It should be obvious therefore that your domain needs to be a fully
> fledged bundle, rather than a fragment. Fragments should really only be
> used for three things:
>
> 1) Localization files
> 2) Platform-specific code
> 3) Unit test code (because the tests in the fragment have full access to
> the classes in the host bundle, even the non-exported packages)
>
> Given then that your domain needs to be in a bundle, you really do need
> to use something like buddy loading. In fact I recommend you use
> "DynamicImport-Package: *" instead of buddy loading, since it is a
> standard OSGi mechanism (whereas buddy loading is specific to Eclipse)
> and in my experience less error prone. It's also very simple to
> understand: if I declare the Hibernate bundle with
> "DynamicImport-Package: *" then when Hibernate attempts to load the
> com.my.domain.Customer class, the classloader will search for a
> com.my.domain package being exported by ANY bundle. Note that
> DynamicImport respects the encapsulation of bundles - it will never
> allow another bundle to load from the non-exported packages of a bundle.
>
> Unfortunately both buddy loading and DynamicImport do also allow you to
> make cyclical dependencies. As with many things they can be used for
> both good and evil.
>
> - Neil
>
>
> Benjamin Pasero wrote:
>
>> Hi,
>
>> I just began considering Fragments for my project, for a simple reason:
>
>> I needed a way to have a library on the exact same classpath as the
>> plugin
>> using it. This is a scenario where Buddy-Classloading or other
>> Classloader
>> hacks actually dont work.
>
>> I was impressed how easy to setup a Fragment. Everything is working fine.
>> There is no classpath issue.
>
>> Now I am curious: Why do people ask for Buddy-Class-Loading, if this
>> problem
>> can easily be solved using Fragments? Is there anything that limits a
> Fragment
>> compared to a Plugin? The only limit I can see is that Fragments don't
>> have
>> an Activator class. But they can still use Extension-Points and
>> participate
>> in contributions.
>
>> Ben
>
Re: Plugins vs. Fragments [message #452778 is a reply to message #452775] Fri, 14 July 2006 12:54 Go to previous messageGo to next message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
> Toplink expects an XML file
> being on the classpath, where it reads persistence settings. Somehow
> Buddy-Classloading did not work in that area.

Resources (eg XML files on the classpath) work exactly like classes do.
The problem is likely to be that Toplink is looking in the default
package, ie assuming that the file has been put at the root of a JAR
somewhere. However you can't export the default package from the OSGi
manifest.

Is it possible to move the XML file into a package directory, eg
"/oracle/config/toplink.xml"? Then you can export the package
"oracle.config" from the bundle. This depends on whether Toplink uses a
hardcoded path to its XML file. I hope it can take a system property
telling it to look somewhere else... if not, complain to Oracle!

Regards
Neil
Re: Plugins vs. Fragments [message #452779 is a reply to message #452775] Fri, 14 July 2006 13:51 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Benjamin Pasero wrote:

> Neil Bartlett wrote:
>> Benjamin,
>
> Hi Neil,
>
> interesting, I never heard of DynamicImport before. I will give it
> a try. While I am able to use Buddy-Classloading to get the Database
> work with Oracly Toplink, I am unable to seperate Toplink from my
> Domain, even with Buddy-Classloading. Toplink expects an XML file
> being on the classpath, where it reads persistence settings. Somehow
> Buddy-Classloading did not work in that area.
>

Yes, this is one of the main reasons of the bug report that spawned buddy
loading. Their is an associated bug report about the serialization issue
and several complained that buddy loading did not address the serialization
issue. I think the serialization bug is still open.

your plugin should provide a service not wrap a library.

> I agree that the domain-plugin should not be dependant on the JPA
> (or as in your example Hibernate) plugin. Currently its the other
> way around: The JPA (Library) Plugin is a Fragment with the domain-
> plugin as Host:
>

The "JPA plugin" is not a library, its a service. it should provide
something the main plugin needs. These should not be conflated.

Probably call it JPADatastore. Your main plugin should have an extension
point that JPADatastore can implement. That way main can look for
implementors of its extension point, and then use them to get instances of
the required classes. All the while main has no knowledge of JPA not even
through buddy or fragment.

I'm going to have to list this architecture on my website because its not so
easy to explain.

> org.mydomain: Plugin containing Model that is to be persisted
> org.jpa: Fragment containing JPA library. Host is org.mydomain
> org.db: Fragment containing DB-JDBC-Library. Host is org.mydomain
>
> (org.db can either be a Fragment or a Plugin. As mentioned, I was able
> to use Buddy-Classloading in that area).
>
> As you can see, all these libraries are actually tightly coupled to
> the domain-plugin. There is no requirement to use them outside the
> model (e.g. as a Library for other services).
>

they should be separated anyway for good design.

> If someone is going to extend my model, he depends on my Model anyways
> and will get JPA as a dependancy automatically (by using ExportApis:true).
>
>

Looks bad.


> Anyways, I am giving DynamicImport a try, since I feel better using real
> plugins.
>
> Ben
>



--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452783 is a reply to message #452779] Fri, 14 July 2006 14:19 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
CL [dnoyeb] Gilbert wrote:
> Benjamin Pasero wrote:
>
>> Neil Bartlett wrote:
>>> Benjamin,
>> Hi Neil,
>>
>> interesting, I never heard of DynamicImport before. I will give it
>> a try. While I am able to use Buddy-Classloading to get the Database
>> work with Oracly Toplink, I am unable to seperate Toplink from my
>> Domain, even with Buddy-Classloading. Toplink expects an XML file
>> being on the classpath, where it reads persistence settings. Somehow
>> Buddy-Classloading did not work in that area.
>>
>
> Yes, this is one of the main reasons of the bug report that spawned buddy
> loading. Their is an associated bug report about the serialization issue
> and several complained that buddy loading did not address the serialization
> issue. I think the serialization bug is still open.
>
> your plugin should provide a service not wrap a library.
>
>> I agree that the domain-plugin should not be dependant on the JPA
>> (or as in your example Hibernate) plugin. Currently its the other
>> way around: The JPA (Library) Plugin is a Fragment with the domain-
>> plugin as Host:
>>
>
> The "JPA plugin" is not a library, its a service. it should provide
> something the main plugin needs. These should not be conflated.

The JPA-Plugin is really just the JPA libraries, nothing more.

>
> Probably call it JPADatastore. Your main plugin should have an extension
> point that JPADatastore can implement. That way main can look for
> implementors of its extension point, and then use them to get instances of
> the required classes. All the while main has no knowledge of JPA not even
> through buddy or fragment.

Thats not working. In order to use JPA, my Main Plugin (Model / Domain), uses
Annotations that it gets from the JPA libraries. I am not planning to let the
persistence-layer be contributable (e.g. JPA or not JPA), but just the database
that JPA may use.

>
> I'm going to have to list this architecture on my website because its not so
> easy to explain.
>
>> org.mydomain: Plugin containing Model that is to be persisted
>> org.jpa: Fragment containing JPA library. Host is org.mydomain
>> org.db: Fragment containing DB-JDBC-Library. Host is org.mydomain
>>
>> (org.db can either be a Fragment or a Plugin. As mentioned, I was able
>> to use Buddy-Classloading in that area).
>>
>> As you can see, all these libraries are actually tightly coupled to
>> the domain-plugin. There is no requirement to use them outside the
>> model (e.g. as a Library for other services).
>>
>
> they should be separated anyway for good design.
>
>> If someone is going to extend my model, he depends on my Model anyways
>> and will get JPA as a dependancy automatically (by using ExportApis:true).
>>
>>
>
> Looks bad.

Thats the only way to avoid duplicate JPA libraries. If someone is contributing
model-code, it needs JPA on the classpath.

>
>
>> Anyways, I am giving DynamicImport a try, since I feel better using real
>> plugins.
>>
>> Ben
>>
>
>
>
Re: Plugins vs. Fragments [message #452787 is a reply to message #452783] Fri, 14 July 2006 18:04 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

After reading your reply I came away confused. You say "I agree that the
domain-plugin should not be dependant on the JPA." But then you also say
"In order to use JPA, my Main Plugin (Model / Domain), uses Annotations
that it gets from the JPA libraries."

Those seem to be conflicting. What is an annotation and how does one 'use'
it from a library?

I don't understand what you need buddy loading for. Or perhaps I am just
agreeing that you were correct when you chose to implement by using a
fragment. Its cleaner to use a fragment than to use a plugin and add buddy
loading.


Benjamin Pasero wrote:



> CL [dnoyeb] Gilbert wrote:
>> Benjamin Pasero wrote:
>>
>>
>> your plugin should provide a service not wrap a library.
>>
>>> I agree that the domain-plugin should not be dependant on the JPA
>>> (or as in your example Hibernate) plugin. Currently its the other
>>> way around: The JPA (Library) Plugin is a Fragment with the domain-
>>> plugin as Host:
>>>
>>
>> The "JPA plugin" is not a library, its a service. it should provide
>> something the main plugin needs. These should not be conflated.
>
> The JPA-Plugin is really just the JPA libraries, nothing more.
>
>>
>> Probably call it JPADatastore. Your main plugin should have an extension
>> point that JPADatastore can implement. That way main can look for
>> implementors of its extension point, and then use them to get instances
>> of
>> the required classes. All the while main has no knowledge of JPA not
>> even through buddy or fragment.
>
> Thats not working. In order to use JPA, my Main Plugin (Model / Domain),
> uses Annotations that it gets from the JPA libraries. I am not planning to
> let the persistence-layer be contributable (e.g. JPA or not JPA), but just
> the database that JPA may use.

Ahh, I understand now. This is somewhat like what I do. My business layer
exposes a persistence extension point that can be implemented by a plugin
that intends to provide persistence. I have two implementing plugins. One
is home grown JDBC persistence, the other is JDO. The JDO plugin lets the
user choose the JDO implementation at runtime as well as which JDBC driver
to use. So the JDO plugin I have is like your whole setup. You have JPA
and you let the user choose the JDBC driver.

I used to implement the JDO/JDBC plugins as fragments. You understand why.
But they were buggy because nobody uses them this way and so they are not
tested this way. They may work fine now, I don't know. When I converted
to plugin, I hit some classpath issues. This is because I was storing
classes in my main plugin that were actually instances from my JDO plugin.
e.g.

IMainClass i = getClassXXX();

where the interface IMainClass is defined in my main plugin but the instance
returned by getClassXXX is from the JDO plugin. So when I try to
deserialize, the classloader can not locate the class. But this does not
seem to match your issue. What exactly is your issue that you think can be
fixed by buddy loading?


--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452788 is a reply to message #452760] Fri, 14 July 2006 13:39 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

I really wish people would stop spreading this as proper coding practice.

Neil Bartlett wrote:

> Benjamin,
>
> There is a very important use case where Buddy classloading (or
> DynamicImport-Package, which I prefer) is needed. The rule is essentially
> this: if a bundle does any form of Reflection or dynamic runtime
> classloading, it needs to use Buddy/DynamicImport.
>

Its not *needed*. Its just easy to use.

> The canonical example is a Hibernate bundle. Say you are using Hibernate
> to map a database table to your Customer class. The Customer class sits in
> package com.my.domain in the "domain" bundle. In order to produce
> instances of customer, Hibernate must dynamically access the class (using
> Class.forName() or similar) and instantiate it.
>

Canonical example is what you stated + a library chosen at runtime.

> Now you can't just make your Hibernate bundle depend on your domain
> bundle, either through Import-Package or Require-Bundle. Hibernate is a
> generic service, it should not have a design time dependency on your
> specific domain. You don't know what other domains Hibernate might be used
> with later, and anyway this would create a cyclical dependency.

Clearly your hibernate bundle *does* depend on your domain bundle. Using
buddy loading does not change this.

If you want to break the dependency you need to pass the required class
loader to the 'hibernate plugin' and let it load the classes that way. Now
the hibernate plugin does not care about where the request came from, and
the requesting plugin NOWHERE references the hibernate plugin not even in a
buddy loading statement. What you do need is a hibernate plugin to
implement an extension point of the main plugin. This requires a paradigm
shift which I will address below.

>
> Neither can you make your domain bundle into a fragment of the Hibernate
> bundle, because that would tightly couple you to the Hibernate bundle. Eg
> you could not deliver your domain without Hibernate coming along too. Also
> a fragment can only be hosted by a single bundle, so if you have any other
> reflection intensive bundles (eg Spring) then you would have to create a
> whole separate fragment.
>
> It should be obvious therefore that your domain needs to be a fully
> fledged bundle, rather than a fragment. Fragments should really only be
> used for three things:
>
> 1) Localization files
> 2) Platform-specific code
> 3) Unit test code (because the tests in the fragment have full access to
> the classes in the host bundle, even the non-exported packages)

Fragments should be uses as the user sees fit based on what they do. Your 3
uses are fine, but do not discourage other uses.

>
> Given then that your domain needs to be in a bundle, you really do need to
> use something like buddy loading. In fact I recommend you use
> "DynamicImport-Package: *" instead of buddy loading, since it is a
> standard OSGi mechanism (whereas buddy loading is specific to Eclipse) and
> in my experience less error prone. It's also very simple to understand: if
> I declare the Hibernate bundle with "DynamicImport-Package: *" then when
> Hibernate attempts to load the com.my.domain.Customer class, the
> classloader will search for a com.my.domain package being exported by ANY
> bundle. Note that DynamicImport respects the encapsulation of bundles - it
> will never allow another bundle to load from the non-exported packages of
> a bundle.
>

The problem is people create 'hibernate plugins' and think its just a
wrapper for some hibernate jar files. They fail to realize this plugin
should provide a _service_, not just wrap a library. They do this because
they have a strange idea that this one hibernate plugin should serve lots
of other plugins (just like a jar file can).

There will be a dependency, this can not be eliminated. Either hibernate
will depend on your main plugin, or many main plugins can depend on this
one hibernate plugin. I think we agree that the main should not depend on
hibernate. Not even through a buddy system. What if you wanted to change
to JDO? or JDBC? or EJB?

Therefore, hibernate must depend on the main plugin. Once this is
recognized and accepted, many creative solutions become available. Such as
extension points. Which is what I use and is why I can have a JDO
implementation a JDBC implementation and a hibernate implementation without
buddy loading and without the main being dependent on any of the datastore
implementations, even though a buddy system.


> Unfortunately both buddy loading and DynamicImport do also allow you to
> make cyclical dependencies. As with many things they can be used for both
> good and evil.
>
> - Neil
>
> Benjamin Pasero wrote:
>
>> Hi,
>

--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452789 is a reply to message #452788] Fri, 14 July 2006 21:32 Go to previous messageGo to next message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
CL [dnoyeb] Gilbert wrote:
> I really wish people would stop spreading this as proper coding practice.

I'm sorry but I disagree with you. I believe that what I described,
using DynamicImport-Package, IS good practice. Later in your message you
chide me for discouraging alternative uses of fragments... fine, if you
reciprocate and allow that my suggested solution (disagree with it
though you may) is at least well thought out, works well for me and not
simply an arbitrary and foolish hack.

As you have shown, there are two ways to do crack this nut, by coming at
it from completely different directions. I don't think Hibernate is a
"service" as you describe it, because it wasn't written as one. Gavin
King et al did not have OSGI in mind as a deployment platform when they
developed Hibernate, so they could not have designed it as an OSGI
service. Therefore either it must be used as a library, or you must add
code to adapt it to that purpose.

> The problem is people create 'hibernate plugins' and think its just a
> wrapper for some hibernate jar files. They fail to realize this plugin
> should provide a _service_, not just wrap a library. They do this because
> they have a strange idea that this one hibernate plugin should serve lots
> of other plugins (just like a jar file can).

Can you explain why you believe this is a strange idea?

> There will be a dependency, this can not be eliminated. Either hibernate
> will depend on your main plugin, or many main plugins can depend on this
> one hibernate plugin.

I think you're failing to distinguish between compile-time depdencies
and runtime ones. Hibernate does need a runtime dependency on domain
classes, because it must instantiate them, but it does not "understand"
those classes - it merely passes them on to another bundle that does
understand them. I do not believe that it is necessary to represent this
runtime dependency with a compile-time declaration such as
Import-Package/Require-Bundle, since Hibernate can quite happily exist
in isolation from any domain bundle.


Regards
Neil
> I think we agree that the main should not depend on
> hibernate. Not even through a buddy system. What if you wanted to change
> to JDO? or JDBC? or EJB?

Agreed. I prefer to achieve this through the OSGI service registry. I
have a DAO interface (eg CustomerDAO) and I can register any
implementation (eg HibernateCustomerDAO). The bundle implementing
HibernateCustomerDAO must of course have a dependency on Hibernate, but
the "main" bundle does not have a dependency on that bundle.
Re: Plugins vs. Fragments [message #452798 is a reply to message #452787] Sat, 15 July 2006 09:37 Go to previous messageGo to next message
Benjamin Pasero is currently offline Benjamin PaseroFriend
Messages: 337
Registered: July 2009
Senior Member
CL [dnoyeb] Gilbert wrote:
> After reading your reply I came away confused. You say "I agree that the
> domain-plugin should not be dependant on the JPA." But then you also say
> "In order to use JPA, my Main Plugin (Model / Domain), uses Annotations
> that it gets from the JPA libraries."
>
> Those seem to be conflicting. What is an annotation and how does one 'use'
> it from a library?
>
> I don't understand what you need buddy loading for. Or perhaps I am just
> agreeing that you were correct when you chose to implement by using a
> fragment. Its cleaner to use a fragment than to use a plugin and add buddy
> loading.

Yep I was not very specific with that. What I wanted to say is that the domain
plugin has no explicit OSGi dependancy to JPA, but it has a dependancy to the
libraries inside. Since JPA is a Fragment, the libraries get on the Domain
Plugins classpath anyways.

Looks like a Fragment is really the only way to seperate JPA as a Library from
the Domain Plugin. Buddy-Loading is not working because of the XML file that
JPA expects on the root of the classpath (actually in META-INF).

>
>
> Benjamin Pasero wrote:
>
>
>
>> CL [dnoyeb] Gilbert wrote:
>>> Benjamin Pasero wrote:
>>>
>>>
>>> your plugin should provide a service not wrap a library.
>>>
>>>> I agree that the domain-plugin should not be dependant on the JPA
>>>> (or as in your example Hibernate) plugin. Currently its the other
>>>> way around: The JPA (Library) Plugin is a Fragment with the domain-
>>>> plugin as Host:
>>>>
>>> The "JPA plugin" is not a library, its a service. it should provide
>>> something the main plugin needs. These should not be conflated.
>> The JPA-Plugin is really just the JPA libraries, nothing more.
>>
>>> Probably call it JPADatastore. Your main plugin should have an extension
>>> point that JPADatastore can implement. That way main can look for
>>> implementors of its extension point, and then use them to get instances
>>> of
>>> the required classes. All the while main has no knowledge of JPA not
>>> even through buddy or fragment.
>> Thats not working. In order to use JPA, my Main Plugin (Model / Domain),
>> uses Annotations that it gets from the JPA libraries. I am not planning to
>> let the persistence-layer be contributable (e.g. JPA or not JPA), but just
>> the database that JPA may use.
>
> Ahh, I understand now. This is somewhat like what I do. My business layer
> exposes a persistence extension point that can be implemented by a plugin
> that intends to provide persistence. I have two implementing plugins. One
> is home grown JDBC persistence, the other is JDO. The JDO plugin lets the
> user choose the JDO implementation at runtime as well as which JDBC driver
> to use. So the JDO plugin I have is like your whole setup. You have JPA
> and you let the user choose the JDBC driver.
>
> I used to implement the JDO/JDBC plugins as fragments. You understand why.
> But they were buggy because nobody uses them this way and so they are not
> tested this way. They may work fine now, I don't know. When I converted
> to plugin, I hit some classpath issues. This is because I was storing
> classes in my main plugin that were actually instances from my JDO plugin.
> e.g.
>
> IMainClass i = getClassXXX();
>
> where the interface IMainClass is defined in my main plugin but the instance
> returned by getClassXXX is from the JDO plugin. So when I try to
> deserialize, the classloader can not locate the class. But this does not
> seem to match your issue. What exactly is your issue that you think can be
> fixed by buddy loading?
>
>
Re: Plugins vs. Fragments [message #452804 is a reply to message #452789] Sun, 16 July 2006 02:04 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Neil Bartlett wrote:

> CL [dnoyeb] Gilbert wrote:
>> I really wish people would stop spreading this as proper coding practice.
>
> I'm sorry but I disagree with you. I believe that what I described,
> using DynamicImport-Package, IS good practice. Later in your message you
> chide me for discouraging alternative uses of fragments... fine, if you
> reciprocate and allow that my suggested solution (disagree with it
> though you may) is at least well thought out, works well for me and not
> simply an arbitrary and foolish hack.
>

No its not arbitrary or foolish but I do think its a hack that gets the
problem out of the way so you can continue to code on something else.


> Regards
> Neil
>> I think we agree that the main should not depend on
>> hibernate. Not even through a buddy system. What if you wanted to
>> change to JDO? or JDBC? or EJB?
>
> Agreed. I prefer to achieve this through the OSGI service registry. I
> have a DAO interface (eg CustomerDAO) and I can register any
> implementation (eg HibernateCustomerDAO). The bundle implementing
> HibernateCustomerDAO must of course have a dependency on Hibernate, but
> the "main" bundle does not have a dependency on that bundle.

Are you saying that HibernateCustomerDAO is a bundle, that depends on a
HibernateLibrary bundle, and it also depends on the main bundle?

If so, my question is why is there even a HibernateLibrary bundle? Why
don't you just include the hibernate jar into the HibernateCustomerDAO
bundle?

Also how does main find the HibernateCustomerDAO? extension point? Is 'OSGI
service registry' equivalent to an extension point?




--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452805 is a reply to message #452798] Sun, 16 July 2006 02:11 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Benjamin Pasero wrote:

> CL [dnoyeb] Gilbert wrote:
>> After reading your reply I came away confused. You say "I agree that the
>> domain-plugin should not be dependant on the JPA." But then you also say
>> "In order to use JPA, my Main Plugin (Model / Domain), uses Annotations
>> that it gets from the JPA libraries."
>>
>> Those seem to be conflicting. What is an annotation and how does one
>> 'use' it from a library?
>>
>> I don't understand what you need buddy loading for. Or perhaps I am just
>> agreeing that you were correct when you chose to implement by using a
>> fragment. Its cleaner to use a fragment than to use a plugin and add
>> buddy loading.
>
> Yep I was not very specific with that. What I wanted to say is that the
> domain plugin has no explicit OSGi dependancy to JPA, but it has a
> dependancy to the libraries inside. Since JPA is a Fragment, the libraries
> get on the Domain Plugins classpath anyways.
>
> Looks like a Fragment is really the only way to seperate JPA as a Library
> from the Domain Plugin. Buddy-Loading is not working because of the XML
> file that JPA expects on the root of the classpath (actually in META-INF).
>

But this file 'belongs' to JPA. Why is it part of the main plugin then?
This is one of my big issues. Without the JPA plugin, the XML file is
meaningless, therefore the JPA plugin is actually the owner of the XML
file, not the main plugin.

If you were to do a different implementation, the XML file would again be
meaningless because its not part of main its part of JPA. If you updated
to JPA5.0 or whatever that used a different XML format, then created a new
additional JPA plugin, how would you isolate the old JPA from the new JPA
with the XML file in the main plugin? What about a different
implementaiton like Hibernate or JDO. Would you put the .jdo files in the
main plugin? It would not understand them...


I had a similar situation. What I did was ask the implementing plugin to
give the main plugin a token that refers to the XML file. So my main
plugin has a token that it passes to the JPA plugin (so to speak). The JPA
plugin maps that token to the XML file. Thus, every plugin is in charge of
only the things it understands.


--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452811 is a reply to message #452804] Sun, 16 July 2006 22:52 Go to previous messageGo to next message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
CL [dnoyeb] Gilbert wrote:

> Are you saying that HibernateCustomerDAO is a bundle, that depends on a
> HibernateLibrary bundle, and it also depends on the main bundle?

HibernateCustomerDAO would be in a bundle, yes. For sake of illustration
lets call that bundle "hibernateCustDAO" although I expect it would have
other DAOs in there as well.

The interface that HibernateCustomerDAO implements is called CustomerDAO
and that would reside in bundle "daos". Obviously hibernateCustDAO would
need to import packages from the "daos" bundle otherwise it would be
impossible to implement the interface. Also since HibernateCustomerDAO
calls Hibernate API methods, it has a dependency on the Hibernate bundle.

The "main" bundle would not care about which implementation of CustomerDAO
it gets, it just cares about the interface, so it has a dependency on the
"daos" bundle only. The domain classes would have to live somewhere too,
probably their own bundle called "domain", because both "main" and "daos"
would have to depend on them.

> If so, my question is why is there even a HibernateLibrary bundle? Why
> don't you just include the hibernate jar into the HibernateCustomerDAO
> bundle?

That would work, but there might be other bundles that want to use
Hibernate. My bundle might be deployed into an application that already
has multiple other bundles using Hibernate. It would be selfish and
inefficient for every bundle to package all of its 3rd party libraries as
private internal JARs.

Secondarily, nested JARs inside bundles cause problems on certain
deployments. Eg if you are deploying to webstart, then all of your bundles
must be JARs - you cannot have directory-based bundles. Therefore if there
are any nested JARs they must be extracted at runtime every time the
application is launched.

Therefore (in my opinion) a simple wrapped Hibernate library is the most
generically useful form for it to take.

> Also how does main find the HibernateCustomerDAO? extension point? Is 'OSGI
> service registry' equivalent to an extension point?

It is similar in a way. It's a core part of OSGI whereas extension points
come from pre-3.0 Eclipse.

Essentially an implementing bundle (hibernateCustDAO in our case)
publishes an object to the service registry under the name of an
interface. Ie it declares "I have an implementation of CustomerDAO
available, here it is". The consuming bundle (ie "main") queries the
registry: "give me an implementation of CustomerDAO". The consumer doesn't
know what implementation it receives - in fact the implementation class
(HibernateCustomerDAO) doesn't even need to be exported from the bundle.

For more information, try this presentation from EclipseCon (given by
Thomas Watson and Peter Kriens):
http://eclipsezilla.eclipsecon.org/php/attachment.php?bugid= 176

Or of course there is always the OSGI spec:
http://www.osgi.org/osgi_technology/download_specs.asp?secti on=2

Kind regards
Neil
Re: Plugins vs. Fragments [message #452822 is a reply to message #452811] Mon, 17 July 2006 13:16 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Neil Bartlett wrote:

> CL [dnoyeb] Gilbert wrote:
>
>> Are you saying that HibernateCustomerDAO is a bundle, that depends on a
>> HibernateLibrary bundle, and it also depends on the main bundle?
>
> HibernateCustomerDAO would be in a bundle, yes. For sake of illustration
> lets call that bundle "hibernateCustDAO" although I expect it would have
> other DAOs in there as well.
>
> The interface that HibernateCustomerDAO implements is called CustomerDAO
> and that would reside in bundle "daos". Obviously hibernateCustDAO would
> need to import packages from the "daos" bundle otherwise it would be
> impossible to implement the interface. Also since HibernateCustomerDAO
> calls Hibernate API methods, it has a dependency on the Hibernate bundle.
>
> The "main" bundle would not care about which implementation of CustomerDAO
> it gets, it just cares about the interface, so it has a dependency on the
> "daos" bundle only. The domain classes would have to live somewhere too,
> probably their own bundle called "domain", because both "main" and "daos"
> would have to depend on them.
>

Got it. This makes sense and is similar to what I do.

>> If so, my question is why is there even a HibernateLibrary bundle? Why
>> don't you just include the hibernate jar into the HibernateCustomerDAO
>> bundle?
>
> That would work, but there might be other bundles that want to use
> Hibernate. My bundle might be deployed into an application that already
> has multiple other bundles using Hibernate. It would be selfish and
> inefficient for every bundle to package all of its 3rd party libraries as
> private internal JARs.
>

I think its infact dangerous for every bundle to try to use the same
hibernate library. It would force all bundles to be bound and tested to
the same release of hibernate. If one needed to upgraded, they would all
have to. Anyway, I suppose this is a side point and we all have our own
dependencies to juggle.

The main point is, where is the requirement for buddy-loading in all of
this? It should not be a problem for the HibernateCustomerDAO to depend
directly on the HibernateLibrary bundle. This is what I do sort of.
Which bundle is buddy loading which? Which has the buddy loading statement
in its manifest?


> Secondarily, nested JARs inside bundles cause problems on certain
> deployments. Eg if you are deploying to webstart, then all of your bundles
> must be JARs - you cannot have directory-based bundles. Therefore if there
> are any nested JARs they must be extracted at runtime every time the
> application is launched.
>
> Therefore (in my opinion) a simple wrapped Hibernate library is the most
> generically useful form for it to take.
>
>> Also how does main find the HibernateCustomerDAO? extension point? Is
>> 'OSGI service registry' equivalent to an extension point?
>
> It is similar in a way. It's a core part of OSGI whereas extension points
> come from pre-3.0 Eclipse.
>
> Essentially an implementing bundle (hibernateCustDAO in our case)
> publishes an object to the service registry under the name of an
> interface. Ie it declares "I have an implementation of CustomerDAO
> available, here it is". The consuming bundle (ie "main") queries the
> registry: "give me an implementation of CustomerDAO". The consumer doesn't
> know what implementation it receives - in fact the implementation class
> (HibernateCustomerDAO) doesn't even need to be exported from the bundle.
>
> For more information, try this presentation from EclipseCon (given by
> Thomas Watson and Peter Kriens):
> http://eclipsezilla.eclipsecon.org/php/attachment.php?bugid= 176
>

I made a few changed more toward OSGI when my last upgrade to 3.1 I believe.
I suppose I can make some more moving toward 3.2. I'll check that out.

> Or of course there is always the OSGI spec:
> http://www.osgi.org/osgi_technology/download_specs.asp?secti on=2
>
> Kind regards
> Neil

--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452827 is a reply to message #452822] Mon, 17 July 2006 13:35 Go to previous messageGo to next message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
CL [dnoyeb] Gilbert wrote:
> I think its infact dangerous for every bundle to try to use the same
> hibernate library. It would force all bundles to be bound and tested to
> the same release of hibernate. If one needed to upgraded, they would all
> have to. Anyway, I suppose this is a side point and we all have our own
> dependencies to juggle.

So mark the Hibernate bundle with a version number, then each bundle that
uses Hibernate can bind to the version of Hibernate that it expects.
There's no problem having plugin A depending on Hibernate v3.0.0 at the
same time plugin B depends on Hibernate v3.1.0, all while running in the
same JVM. This is the power of the OSGi classloading architecture.

> The main point is, where is the requirement for buddy-loading in all of
> this? It should not be a problem for the HibernateCustomerDAO to depend
> directly on the HibernateLibrary bundle. This is what I do sort of.
> Which bundle is buddy loading which? Which has the buddy loading statement
> in its manifest?

The Hibernate bundle itself still has to do this, because somewhere deep
inside Hibernate there is code that looks something like this:

Class beanClass = Class.forName(beanNameSupplied);
beanClass.newInstance();

That is why Hibernate must use Buddy-Policy or DynamicImport-Package. Of
course if Hibernate had the ability to use a ClassLoader supplied by its
caller, then there would be no problem. Unfortunately Hibernate doesn't
offer that ability, and neither do 90% of libraries that do reflection -
they are all based on the assumption that there is just one system wide
classloader which will always work.

- Neil
Re: Plugins vs. Fragments [message #452844 is a reply to message #452827] Tue, 18 July 2006 04:29 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: lamont_gilbert.rigidsoftware.com

Neil Bartlett wrote:

> CL [dnoyeb] Gilbert wrote:
>> I think its infact dangerous for every bundle to try to use the same
>> hibernate library. It would force all bundles to be bound and tested to
>> the same release of hibernate. If one needed to upgraded, they would all
>> have to. Anyway, I suppose this is a side point and we all have our own
>> dependencies to juggle.
>
> So mark the Hibernate bundle with a version number, then each bundle that
> uses Hibernate can bind to the version of Hibernate that it expects.
> There's no problem having plugin A depending on Hibernate v3.0.0 at the
> same time plugin B depends on Hibernate v3.1.0, all while running in the
> same JVM. This is the power of the OSGi classloading architecture.
>
>> The main point is, where is the requirement for buddy-loading in all of
>> this? It should not be a problem for the HibernateCustomerDAO to depend
>> directly on the HibernateLibrary bundle. This is what I do sort of.
>> Which bundle is buddy loading which? Which has the buddy loading
>> statement in its manifest?
>
> The Hibernate bundle itself still has to do this, because somewhere deep
> inside Hibernate there is code that looks something like this:
>
> Class beanClass = Class.forName(beanNameSupplied);
> beanClass.newInstance();
>
> That is why Hibernate must use Buddy-Policy or DynamicImport-Package. Of
> course if Hibernate had the ability to use a ClassLoader supplied by its
> caller, then there would be no problem. Unfortunately Hibernate doesn't
> offer that ability, and neither do 90% of libraries that do reflection -
> they are all based on the assumption that there is just one system wide
> classloader which will always work.
>
> - Neil

Ahh. No context loader either? I am surprised as I was under the impression
that most libraries that use reflection will have an option for you to
supply the classloader directly, or they will use the context class loader.
I'll have to go back to blaming this whole situation on Hibernate and grant
you buddy loading does address this. Hopefully hibernate is thread safe
and does not maintain any static data since it will be shared this way.

JDO lets you specify the classloader so I'm not sure about that 90% number.


--
Respectfully,

CL Gilbert
"Verily, verily, I say unto you, He that entereth not by the door() into the
sheepfold{}, but climbeth up some other *way, the same is a thief and a
robber."
Re: Plugins vs. Fragments [message #452850 is a reply to message #452844] Tue, 18 July 2006 09:54 Go to previous message
Neil Bartlett is currently offline Neil BartlettFriend
Messages: 93
Registered: July 2009
Member
CL [dnoyeb] Gilbert wrote:
> Ahh. No context loader either? I am surprised as I was under the impression
> that most libraries that use reflection will have an option for you to
> supply the classloader directly, or they will use the context class loader.
> I'll have to go back to blaming this whole situation on Hibernate and grant
> you buddy loading does address this. Hopefully hibernate is thread safe
> and does not maintain any static data since it will be shared this way.

Well, maybe I'm being unfair to Hibernate. I simply picked it as an
example of a library that does a lot of reflection - I haven't looked at
the code.

> JDO lets you specify the classloader so I'm not sure about that 90% number.

Maybe 90% is too high but it's certainly "plenty". Take for example
Spring... mostly it is well behaved and will accept a ClassLoader, but
there lots of different places in Spring where reflection happens, and at
least a few just use Class.forName().

Another horrible offender is Jakarta Commons Logging which tries to do all
sorts of ClassLoader magic to find a logger implementation on the
classpath, none of which is compatible with OSGi.

Anyway as long as the number is above zero there is, unfortunately, a need
for hacks like BuddyPolicy/DynamicImport.

Regards
Neil
Previous Topic:Automatic build doesn't work(Unable to find
Next Topic:Detecting event for closing view
Goto Forum:
  


Current Time: Mon Oct 07 02:21:31 GMT 2024

Powered by FUDForum. Page generated in 0.03784 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top