Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Equinox » Classloader Questions
Classloader Questions [message #90018] Thu, 07 June 2007 19:53 Go to next message
Brett Humphreys is currently offline Brett HumphreysFriend
Messages: 17
Registered: July 2009
Junior Member
I'm trying to embed Equinox into a J2SE application. This is a legacy
application so I need to be careful what I do and do not change. One
thing I cannot change is a jar I have that is defined on java's
classpath. This jar provides a package called c.a.d.c.boot.

Classes in this package must be visible to the bundles within the
equinox runtime.

So the system classloader has my special package within it. From the
system classloader I spawn a URLClassLoader. From a class within this
URLClassLoader I start the Equinox runtime (via the
EclipseStarter.startup method).

So it occurred to me that this was not all that much different to how
java.* classes are loaded. So I first tried setting the
org.osgi.framework.bootdelegation property to "c.a.d.c.boot.*" (via
EclipseStarter.setInitialProperties before calling startup), this
doesn't seem to have any effect. I've also tried setting the
osgi.parentClassLoader property to "app" and "fwk", still no effect.
Finally , I set org.osgi.framework.system.packages to "c.a.d.c.boot",
this did work, however this seems to be an ill-suited solution as i'm
overwriting everything the JVM is providing (javax.xml.parsers for
example). Every situation ends up with me getting a
NoClassDefFoundError for any import from the c.a.d.c.boot package.

All the properties do seem to be set, per the getprop command on the
equinox console.

So my question is, how can a bundle refer to a class in the package
c.a.d.c.boot without making this package a bundle itself? There seems
to be some discussion out there regarding extension bundles, but I
thought this was overkill as it seems to me that this should be somewhat
solvable through the provided property mechanism.

What am I missing?

Thanks for your help.

-brett
Re: Classloader Questions -- solved. [message #90048 is a reply to message #90018] Thu, 07 June 2007 21:06 Go to previous messageGo to next message
Brett Humphreys is currently offline Brett HumphreysFriend
Messages: 17
Registered: July 2009
Junior Member
Apparently creating a system.bundle fragment was the correct solution.

The final solution was to:
set org.osgi.framework.bootdelegation property to "c.a.d.c.boot.*"
set osgi.parentClassLoader to "app"
create a fragment bundle with no code in it and the following manifest:

Manifest-Version: 1.0
Bundle-SymbolicName: c.a.d.c.boot
Bundle-ManifestVersion: 2
Fragment-Host: system.bundle
Export-Package: c.a.d.c.boot


I didn't realize how crucial the fragment bundle was to bridging these
classloaders.

-Brett
Re: Classloader Questions -- solved. [message #90078 is a reply to message #90048] Fri, 08 June 2007 05:47 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: stepper.sympedia.de

Brett,

The Equinox ServletBridge does a similar trick to export the javax.servlet package of the embedding web container. There the system.bundle fragment is created and persisted on the fly.

But I was not aware that it was necessary to additionally fiddle with any system properties. Have you tried to only deploy your fragment into an otherwise unmodified platform?

Cheers
/Eike


Brett Humphreys schrieb:
> Apparently creating a system.bundle fragment was the correct solution.
>
> The final solution was to:
> set org.osgi.framework.bootdelegation property to "c.a.d.c.boot.*"
> set osgi.parentClassLoader to "app"
> create a fragment bundle with no code in it and the following manifest:
>
> Manifest-Version: 1.0
> Bundle-SymbolicName: c.a.d.c.boot
> Bundle-ManifestVersion: 2
> Fragment-Host: system.bundle
> Export-Package: c.a.d.c.boot
>
>
> I didn't realize how crucial the fragment bundle was to bridging these
> classloaders.
>
> -Brett
>
Re: Classloader Questions -- solved. [message #90093 is a reply to message #90048] Fri, 08 June 2007 06:25 Go to previous messageGo to next message
Danail Nachev is currently offline Danail NachevFriend
Messages: 110
Registered: July 2009
Senior Member
Yes, indeed this is the correct way to do it - if you have a package in
the system classpath, you need to deploy it as a extension bundle
(system.bundle fragment). This way you don't need to set the
bootdelegation property. All you have to do is to import the package in
the bundle which uses it and to setup the parent class loader of the
Equinox correctly.

If you set the bootdelegation property, then you don't need to set
anything (only the class loader hierarchy correctly). When you set the
bootdelegation, you don't need to import the package in the bundles
which are using it.

Danail

Brett Humphreys wrote:
> Apparently creating a system.bundle fragment was the correct solution.
>
> The final solution was to:
> set org.osgi.framework.bootdelegation property to "c.a.d.c.boot.*"
> set osgi.parentClassLoader to "app"
> create a fragment bundle with no code in it and the following manifest:
>
> Manifest-Version: 1.0
> Bundle-SymbolicName: c.a.d.c.boot
> Bundle-ManifestVersion: 2
> Fragment-Host: system.bundle
> Export-Package: c.a.d.c.boot
>
>
> I didn't realize how crucial the fragment bundle was to bridging these
> classloaders.
>
> -Brett
>
Re: Classloader Questions -- solved. [message #90315 is a reply to message #90093] Tue, 12 June 2007 12:51 Go to previous messageGo to next message
Brett Humphreys is currently offline Brett HumphreysFriend
Messages: 17
Registered: July 2009
Junior Member
That's correct, I only needed to do one or the other, setting the
bootdelegating property was overkill, and probably not the direction I
wanted to go.

Thanks everyone for your help.

-Brett

Danail Nachev wrote:
> Yes, indeed this is the correct way to do it - if you have a package in
> the system classpath, you need to deploy it as a extension bundle
> (system.bundle fragment). This way you don't need to set the
> bootdelegation property. All you have to do is to import the package in
> the bundle which uses it and to setup the parent class loader of the
> Equinox correctly.
>
> If you set the bootdelegation property, then you don't need to set
> anything (only the class loader hierarchy correctly). When you set the
> bootdelegation, you don't need to import the package in the bundles
> which are using it.
>
> Danail
>

>>
Re: Classloader Questions -- solved. [message #91045 is a reply to message #90093] Thu, 21 June 2007 17:35 Go to previous messageGo to next message
Brett Humphreys is currently offline Brett HumphreysFriend
Messages: 17
Registered: July 2009
Junior Member
One follow up to this. If I have a 3rd party jar (foo.jar) which provides org.db.foo, that I want
to use within my bundles, but for argument's sake, I'm too lazy to wrap it as a bundle itself, and
too lazy create a system.bundle frag to bridge it. I would have thought I could set the
bootdelegation property to be org.db.foo.* and add add foo.jar to the jvm's classpath and all would
work properly, but this doesn't seem to work at all.

I half expected this to only work with classes in the SystemClassLoader, but the jars on the
classpath I believe are loaded into the system classloader.

That being said, I did add javax.* to the bootdelegation property and that seems to work just fine.
But setting the bootdelegation property to "javax.* org.db.foo.*" worked for swing, but not the
classes in org.db.foo.

What am I missing regarding this property?

Thanks.

-Brett


Danail Nachev wrote:
>
> If you set the bootdelegation property, then you don't need to set
> anything (only the class loader hierarchy correctly). When you set the
> bootdelegation, you don't need to import the package in the bundles
> which are using it.
>
Re: Classloader Questions -- solved. [message #91127 is a reply to message #91045] Fri, 22 June 2007 17:51 Go to previous message
Thomas Watson is currently offline Thomas WatsonFriend
Messages: 503
Registered: July 2009
Senior Member
The parent classloader for bundle classloaders in equinox is the boot
classloader by default (look in eclipse help for the
osgi.parentClassLoader configuration property). That is different that
the "system class loader". The system classloader is actually a
hierarchy of three classloaders

Application -> Extension -> Boot

When you place jars on the jvm's classpath (by using -classpath etc) the
jar ends up on the Application classloader not the boot classloader.
The bootdelegation property delegates to the parent classloader of the
bundle classloader which is boot by default. Setting
osgi.parentClassloader=app should do the trick.

HTH

Tom.
Previous Topic:PDE to pick up non
Next Topic:Http services and contexts
Goto Forum:
  


Current Time: Thu Apr 18 16:11:49 GMT 2024

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

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

Back to the top