dev@glassfish.java.net

Re: [v3] exporting all Metro packages for OSGi

From: Fabian Ritzmann <Fabian.Ritzmann_at_Sun.COM>
Date: Wed, 27 Aug 2008 13:53:30 +0300

On 27. Aug 2008, at 13:49, Sahoo wrote:

> No, I still don't understand why we are seeing failures. My
> understanding is that Metro is a OSGi bundle and some code in that
> OSGi bundle is attempting to load another non-exported class from
> the same OSGi bundle using a variant of Class.forName() that does
> not take any classloader as argument. In such a case,
> Class.forName() uses caller's classloader, which is the classloader
> of the Metro bundle. Such a class loader should be able to load any
> class that's part of Metro bundle.
>
> There are two assumptions here:
> 1. Class being loaded is part of Metro OSGi bundle.
> 2. No classloader is passed to Class.forName().
>
> Is any of them wrong?

Both assumptions are correct. I better leave it to Richard to explain
why Class.forName(String name) is not doing what we are expecting.

Fabian


> Fabian Ritzmann wrote:
>> Hi,
>>
>> Richard has had a look at some of the class loading issues we have
>> had with the Metro bundles. Here is my summary as I understand it
>> and some more comments and questions:
>>
>> Metro code is using Class.forName(String className) to dynamically
>> load classes. In an OSGi environment, these classes usually can not
>> be found unless the packages are explicitly imported. We bumped
>> into this issue when doing META-INF/services look-ups but there are
>> almost certainly other scenarios where this will lead to
>> ClassNotFoundExceptions. GlassFish implemented the
>> WebappClassLoader, which in addition to the OSGi classloaders is
>> loading all classes that are exported. That is why an export of all
>> classes solves the issue for us [1].
>>
>> Richard suggested a few approaches to solve this issue without
>> exporting everything:
>>
>> 1) Replace calls to Class.forName(String className) with
>> Bundle.loadClass(String name).
>>
>> 2) Create a ClassLoader wrapper for Bundle.loadClass.
>>
>> I believe 2) is already close to what we are doing with the
>> WebappClassLoader. 1) doesn't really work for us because Metro
>> libraries are used in a variety of environments, most of which we
>> don't have any control over, and we can't introduce dependencies on
>> OSGi.
>>
>> I believe another solution could be if we manually added the
>> packages in question to the Import-Package manifest header? I am
>> not very comfortable however with checking dozens of libraries for
>> their use of dynamically created classes. The risk that we will be
>> missing some package and it slips through testing is high.
>>
>>
>> Fabian
>>
>>
>> [1] Plus the bnd tool we are using is creating an import statement
>> for every package that is being exported, i.e. by exporting
>> everything we are making sure that all dynamically loaded classes
>> are getting imported as well.