dev@glassfish.java.net

Classloading strategy for OSGi <was> Fwd: [Jersey] Jersey in Felix

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 02 Dec 2008 11:00:45 +0100

Hi,

In the email below Richard is attempting to:

> embed the Jersey jars within my bundle
> and not have any of the Jersey services exported, just have the bundle
> be a self contained module that registers a Servlet as a service to be
> picked up by the web container.


In the JSR-311 jar the method:

   javax.ws.rs.ext.RuntimeDelegate.getInstance()

will attempt to obtain an instance of RuntimeDelegate by loading a
class using the class loader returned from
Thread.currentThread().getContextClassLoader().

Richard states:

> The problem
> is that the Thread class loader is the application classloader, not
> the bundle class loader.

proposes a work around:

> The
> simplest solution is to wrap the initialization code in something that
> sets the threads context class loader to the bundles class loader.


and a possible solution:

> In situations like this I've often seen a
> policy of trying to find a classloader that can load the requested
> class by starting with the getClass().getClassLoader() class loader,
> then trying the Thread class loader and finally trying the system
> class loader.



Do any OSGi experts on the list have any advice w.r.t. to the such
strategies.

Paul.

Begin forwarded message:

> From: Richard Wallace <rwallace_at_thewallacepack.net>
> Date: December 1, 2008 10:19:45 PM CEST
> To: users_at_jersey.dev.java.net
> Subject: Re: [Jersey] Jersey in Felix
> Reply-To: users_at_jersey.dev.java.net
>
> On Mon, Dec 1, 2008 at 2:40 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>> Hi Richard,
>>
>> On Nov 30, 2008, at 1:14 AM, Richard Wallace wrote:
>>
>>> Hey all,
>>>
>>> I'm trying to get Jersey working in Felix and I'm running into a few
>>> problems.
>>
>> Is w.r.t. to utilizing Jersey without specific support in GF v3
>> prelude? for
>> example i understand that GF has support for META-INF/services.
>>
>> We realize we have to do some more work to improve on the OSGi
>> integration.
>> For example currently for GF we rely on the jersey-bundle.jar and
>> IIRC
>> pretty much every package is exported. The reason being is that
>> although
>> Jersey was split into several maven modules the package boundaries
>> between
>> them were not cleanly defined. This has been fixed now so that
>> modules only
>> depend on API/SPI packages of other modules and there is no package
>> names
>> shared between modules. For the 1.0.2 release we hope to add proper
>> OSGI
>> information to each module.
>>
>> If there is any overlap between what you have done and what we
>> would like to
>> do perhaps we can share the details on what additional work you
>> needed to
>> do?
>>
>
> Sorry. I should have described the use-case a bit more clearly. What
> I'm trying to accomplish is to embed the Jersey jars within my bundle
> and not have any of the Jersey services exported, just have the bundle
> be a self contained module that registers a Servlet as a service to be
> picked up by the web container.
>
>>
>>> I've solved most of them but the one I'm running into now
>>> is possibly a showstopper. In the FactoryFinder.find() method of
>>> the
>>> jsr311-api jar there is this call to get the class loader.
>>>
>>> classLoader =
>>> Thread.currentThread().getContextClassLoader();
>>>
>>
>> The context class loader is used consistently throughout Jersey to
>> dynamically load classes: stuff from META-INF/services and classes
>> from
>> names when class scanning for root resource and provider classes.
>>
>
> My question was more meant to find out if it is used outside the scope
> of the initialization? I don't think it is (except for maybe on
> reload which I'm not worried about at the moment) because I've managed
> to get things up and running pretty well.
>
>>
>>> The problem is that the thread class loader is not the bundle class
>>> loader so this fails to find the RuntimeDelegationImpl class.
>>
>> And the RuntimeDelegationImpl will be in another bundle?
>>
>
> No, everything that Jersey needs is in the same bundle. The problem
> is that the Thread class loader is the application classloader, not
> the bundle class loader. In situations like this I've often seen a
> policy of trying to find a classloader that can load the requested
> class by starting with the getClass().getClassLoader() class loader,
> then trying the Thread class loader and finally trying the system
> class loader. It seems that that would make sense here as well.
>
>>
>>> The
>>> simplest solution is to wrap the initialization code in something
>>> that
>>> sets the threads context class loader to the bundles class loader.
>>> I'm worried that even if this works for the startup code, it may
>>> cause
>>> problems down the line. Any tips?
>>>
>>
>> Hmm... i must admit to not being an expert in the class loading
>> esoteric
>> nature of the JVM and how OSGi works in this respect. So it is hard
>> for me
>> to know what problems, if any, this might induce. What types of
>> problem
>> might you expect? What should i be looking for?
>>
>
> I was just wondering if the Thread class loader is used past
> initialization is all. It doesn't look like it is and this could be
> easily fixed by using the class loader searching I described above.
>
> Another thing that would be nice, while I'm on the subject, is to
> split any implementations up. For instance, I'm using the Grizzly web
> server but because the httpserver integration code is bundled in the
> same jar I have no way of excluding it and have to specifically
> configure the maven-bundle-plugin to ignore anything that imports
> com.sun.net.httpserver.* which is rather annoying.
>
> I look forward to seeing how things turn out with Jersey 1.0.2 and
> making Jersey work better in an OSGi environment. I do have a
> use-case coming up where it would be very nice to have a Jersey bundle
> deployed which uses the whiteboard pattern so other bundles could
> register resources to have them picked up automatically, rather than
> having to have to create a separate ServletContainer instance for each
> bundle that will want to use Jersey.
>
> Thanks,
> Rich
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>