Hello.

My impression is that right now, there are not too many users of
pax-wicket (another problem in itself that should be discussed at some
point, but not the purpose of this thread).

I suspect that there may be some classloading issues that will only
surface once people start really using the product in a system with a
lot of dynamic stuff going on.


Lately, I have been using a kind of library bundle with a widget factory
that supplies my applications with a selection of widgets. I find this
more natural and especially much easier than having to register each
individual widget in pax-wicket.

However, due to the way classloading works in this environment,
exceptions are being thrown by Wicket during deserialization of pages.
The reason is because the proper classes cannot be found for these
library widgets.


Edward suggested that I register an IClassResolver for these bundles.
There are a few issues with this approach, however.

First, you need to make sure that the bundle is only supplying a
resolution for classes that it is responsible for. If it replies
anything other than null for classes outside its scope, then strange
things happen. The way I resolved this issue was to put a header in the
library bundle's manifest for the packages for which it is responsible:

Resolver-Packages: com.mycompany.mypackage1,
 com.mycompany.mypackage2,
 com.mycompany.mypackage3

I then have a resolve that I register for the bundle, which looks like
this:

public class BundleClassResolver
    implements IClassResolver
{
    private final BundleContext m_bundleContext; 
    final List<String> m_resolverPackages;

    public BundleClassResolver( final BundleContext bundleContext )
    {
        m_bundleContext = bundleContext;
        final Bundle bundle = m_bundleContext.getBundle();
        @SuppressWarnings("unchecked")
        final Dictionary<String, String> headers = bundle.getHeaders();
        final String[] resolverPackages =
headers.get( "Resolver-Packages" ).split( "," );
        m_resolverPackages = new ArrayList<String>();
        for( final String resolverPackage : resolverPackages )
        {
            m_resolverPackages.add( resolverPackage );
        }
    }

    public Class<?> resolveClass( final String className )
        throws ClassNotFoundException
    {
        final int dotIndex = className.lastIndexOf( '.' );
        final String classPackage = className.substring( 0, dotIndex );
        if( !m_resolverPackages.contains( classPackage ) )
            return null;

        return m_bundleContext.getBundle().loadClass( className );
    }
}


BTW, I noticed that the expected behaviour for the IClassResolver is to
return null if it comes across a class for which it should not take
responsibility, and throw a CNFE if it should be responsible, but cannot
resolve the class.

Anyway, this approach solves the issue in most respects except for one
major problem: there are classes that it should take responsibility for,
but are very difficult to determine in advance. There are imports into
this bundle, and imports of those imports, and so on, and so on.
Actually trying to manage the responsibility of this IClassResolver
sounds like a very complex task that will almost duplicate the OSGi
system itself.



I'm not sure what the best way is to proceed with this. Any useful
suggestions would be really appreciated.


Anyway, this issue leads me to believe that even without using libraries
like I am, the current mechanism in pax-wicket will cause problems down
the line. Currently, it looks like the wrong classloader may be
answering for the resolution of a class that it should not be answering
for.


Thoughts?




_______________________________________________
general mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/general

Reply via email to