Here's a big long winded explanation on how we got Tuscany to work with
Eclipse for now while other solutions are looked at. 

This is all based on the 1.01 branch in the repository. Also, we have no
idea if this is the right or wrong way to do things. But, it's working for
us right now so...

Any feedback would be appreciated. 

Tuscany resource loading in Eclipse RCP

Problem:

Tuscany loads composite configuration files using the class loader
getResource() method, 
but in the eclipse RCP environment, a special class loader is used that
locates the resources
by the bundle (plugin) they are located in. The URL returned by
getResource() is in the form:
"bundleresource://plugin##/resourceName" instead of an absolute file path
starting with "file://".
Since this special type is not handled, Tuscany can not locate any
resources.

Solution:

Eclipse provides a means to add a ClassLoadingHook, which is an interface
that provides methods
that can be implemented to create and use a custom class loader for a
particular bundle (plugin).
The ClassLoaderHook is added to the system by implementing and adding a
HookConfigurator implementation.

A plugin must be created that depends on the org.eclipse.osgi plugin.
Note that all of the classes needed to setup the custom class loader are
marked with restricted access
by eclipse, but may still be implemented and used.

HookConfigurators are loaded by OSGI prior to the bundle loading.

A HookConfigurator (org.eclipse.osgi.baseadaptor.HookConfigurator) has an
addHooks() method which passes in a HookRegistry object. The
addClassLoadingHook() method is used to pass in the new ClassLoadingHook
(org.eclipse.osgi.baseadaptor.hooks.ClassLoadingHook) created.

Within the ClassLoadingHook implementation, the main method of interest is
createClassLoader() which should be used to create a custom class loader
that will properly return the file URLs from getResource() (mentioned
below). All other methods can return null or false accordingly.

A custom class loader could be returned for all plugin bundles, or for
particular bundles based on the use case desired. For adding it to only the
plugin bundles containing Tuscany configuration files, the BaseData object
can be used to determine the bundle name using data.getSymbolicName().

To create the custom class loader, extending the default used by the eclipse
RCP seemed the best approach to not lose any other components of the class
loader. That class is DefaultClassLoader
(org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader) and the only
method that needs to be overridden is getResource(String). The constructor
method must take the same arguments as DefaultClassLoader, and those are the
parameters passed into createClassLoader() in the ClassLoadingHook.

To properly check that the resource being returned was listed with the
custom "bundleresource" prefix, the following code can be used:

public URL getResource(String name) {
    URL resource = super.getResource(name);
    if (resource == null) {
        return null;
    }
    try {
        URLConnection connection = resource.openConnection();
        if (connection instanceof BundleURLConnection) {
            BundleURLConnection bundleConn = (BundleURLConnection)
connection;
            //Gets the absolute File path URL
            return bundleConn.getFileURL();
        }
    }
    catch (IOException e) {
        // Ignore Exception.
    }
    
    return resource;
}

Configuration file:
The final addition to the plugin in the inclusion of a
hookconfigurators.properties" at the base level of the plugin which includes
the following line: hook.configurators=FullClassName

FullClassName is the class name of the HookConfigurator implementation in
the plugin.


Exporting and Use The plugin must now be exported and include the
manifest.mf file, the classes, and the hookconfigurators.properties file.
The plugin must be exported as a JAR (not a folder) and the version number
must be appended on the end (which should happen automatically) in the form
pluginId_version.jar The exported plugin must be placed in the target
platform in the same folder as the org.eclipse.osgi plugin to work properly.

At runtime, for the plugin to be recognized as an extension, one of the
following options must be performed:

1) Config.ini
Add this line to the config.ini of the application:
osgi.framework.extensions=plugin_id_name

2) Runtime VM argument
Add the following line to the VM arguments
-Dosgi.framework.extensions=plugin_id_name

For more details regarding Eclipse Adapter Hooks, see:
http://wiki.eclipse.org/Adaptor_Hooks

-Jason
 

> -----Original Message-----
> From: Jason Clark [mailto:[EMAIL PROTECTED]
> Sent: Tuesday, November 20, 2007 9:11 AM
> To: [email protected]
> Subject: RE: Eclipse RCP apps and Tuscany
> 
> We found a work-around, but it involves using some classes from the
> Eclipse
> internal package, which is frowned upon by them. It's more of a fix for
> eclipse than making the app OSGi friendly though. I'll get more details
> and
> post them soon.
> 
> -Jason
> 
> > -----Original Message-----
> > From: Jean-Sebastien Delfino [mailto:[EMAIL PROTECTED]
> > Sent: Tuesday, November 20, 2007 6:38 AM
> > To: [email protected]
> > Subject: Re: Eclipse RCP apps and Tuscany
> >
> > Jason Clark wrote:
> > > We tried launching Tuscany in an RCP application but ran into a lot of
> > > class loading problems. In particular, for finding resources using
> > > Thread.currentThread().getContextClassLoader and
> > > ClassLoader.getResource, i.e. getting the classLoader from the thread
> or
> > > class. Has anyone run into this problem before?
> > >
> > >
> > >
> > > -Jason Clark
> > >
> >
> > Rajini is currently working on making the Tuscany runtime OSGi-friendly
> > and has run into similar problems.
> >
> > What you describe is a good and increasingly common use case for
> > Tuscany, I think we should have a sample plus an integration test using
> > Tuscany from RCP.
> >
> > Are you interested in contributing a test case? Then we can fix the
> > runtime to make it work, and once the test case is in the build we can
> > make sure that it continues to work over time :)
> >
> > --
> > Jean-Sebastien
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> 
> 








---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to