Hello Stian,

thank you for your assistance and that you have taken the time to 
support my plugin development. I will adept my sources to your 
suggestions. Wish you a nice weekend!

Regards
Andreas

Stian Soiland-Reyes schrieb:
> On Thu, May 27, 2010 at 19:36, Andreas Truszkowski <[email protected]> 
> wrote:
>   
>> if I try to install my plugin via "Find new plugins" the updates and
>> plugins manager installs all dependencies without an error. But when I
>> restart Taverna the plugin is not visible. Starting Taverna in debug
>> mode shows also no errors or any sign for a problem. How can I find the
>> reason why the plugin is not loaded accurate. Here is the URL to the plugin:
>> http://www.ts-concepts.de/cdk-taverna2/plugin/
>>     
>
> The log file in ~/.taverna-2.1.2/logs says:
>
> INFO  2010-05-28 11:19:40,187
> (net.sf.taverna.t2.workbench.ui.servicepanel.ServicePanel:131) -
> Updating My example service
> ..
> INFO  2010-05-28 11:19:40,288
> (net.sf.taverna.t2.workbench.ui.servicepanel.ServicePanel:131) - Found
> 0 services My example service
>
> .. so it is installed, just not listed under "Import new services"
>
>
>   
>> >From what I see in
>>     
> http://www.ts-concepts.de/cdk-taverna2/maven/release_repository/org/openscience/cdk/applications/taverna/cdk-taverna-2-activity-ui/0.1/cdk-taverna-2-activity-ui-0.1-sources.jar
> in CDKServiceProvider:
>
>    List<ServiceDescription> results = new ArrayList<ServiceDescription>();
>             List<Class> classes =
> CDKClassGrabber.getClassessOfSuperclass("org.openscience.cdk.applications.taverna",
>                     AbstractCDKActivity.class);
>             // Register activities
>             for (Class<? extends AbstractCDKActivity> activityClass : 
> classes) {
>                 AbstractCDKActivity activity = activityClass.newInstance();
>                 service = new CDKServiceDescriptor(activityClass);
>                 service.setActivityName(activity.getActivityName());
>                 service.setFolderName(activity.getFolderName());
>                 // TODO set description
>                 service.setDescription(activity.getDescription());
>
> service.setConfigurationPanelClass(CDKClassGrabber.getClassByName("org.openscience.cdk.applications.taverna",
>                         activity.getConfigurationPanelClass()));
>
> service.setAdditionalProperties(activity.getAdditionalProperties());
>                 results.add(service);
>             }
>
> As this is returning 0 services, I believe that the list "classes" is empty.
>
> It seems we are moving into the dark territory of classloaders. Here be 
> dragons!
>
>
> There seems to be a big hint that some Class.forName() or similar is
> being done here in this CDKClassGrabber.getClassessOfSuperclass - but
> remember that when installed as a plugin you will not have the CDK
> classes on the System classloader, only on the classloader of your
> plugin as you will now be running inside the plugin system Raven.
>
> So it depends on how CDKClassGrabber looks up those classes. If it
> tries to use ClassLoader.getSystemClassLoader() it would not find any
> implementations, as this would only find classes in JARs that are in
> Taverna's lib/ folder.
>
> your CDKClassGrabber.getClassesForPackage does:
>
> ClassLoader cld = Thread.currentThread().getContextClassLoader();
>
> .. and tries to use this to look for URLs matching your package name.
>
>
> While running from Eclipse this should work, as the context class
> loader is the system class loader, which knows about everything on
> your classpath, including the project with CDKClassGrabber etc. While
> running in Taverna the default context class loader will just know
> about the lib/ folder.
>
>
> A quick fix would therefore be to change the context class loader in
> CDKServiceProvider before calling CDKClassGrabber. This should be
> fairly safe, as each service provider is run in a different thread.
> Try something like:
>
> Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
>
>
> Another important thing to know in this aspect is that Raven class
> loaders are arranged hierarchical, one per POM file. Tthe classloader
> for
> cdk-taverna-2-activity-ui will search the classloaders for each of its
> dependencies, so it will search cdk-taverna-2-activity, which then
> again will search its dependencies, like org.openscience.cdk:cdk. But
> it is important to know that this does not go backwards, so
> cdk-taverna-2-activity is not able to find any classes in
> cdk-taverna-2-activity-ui as it does not depend on it. (Doing so would
> form a loop).
>
> So if you wanted CDKClassGrabber in cdk-taverna-2-activity to find any
> classes in cdk-taverna-2-activity-ui, then the only way would be
> either to pass in the ClassLoader itself as a parameter, or to set the
> context classloader and use that from within CDKClassGrabber.
>
>
> Now as for the clever bit that looks at the JAR files, I would
> recommend rather to go for the slightly more standard SPI approach as
> you've already seen in
> ./META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider
> and 
> ./META-INF/services/net.sf.taverna.t2.workbench.ui.views.contextualviews.activity.ContextualViewFactory
>
>
> So I would go for
> META-INF/services/org.openscience.cdk.applications.taverna.AbstractCDKActivity
> - and in that file(s) list:
>
> org.openscience.cdk.applications.taverna.io.MDLSDFileWriterActivity
> org.openscience.cdk.applications.taverna.io.SMILESFileReaderActivity
>
> etc.
>
> To find those implementations of AbstractCDKActivity you can use our
> SPI registry, which would check all plugins (and not just your own)
> for the SPI description files, and use the classloaders where it finds
> such files to instantiate those activities.
>
> We have two versions, one that can find the classes, and another one
> that finds the classes and makes a (singleton) instance of that class.
> As you'll
>
> You can use it like this:
>
> import net.sf.taverna.t2.spi.SPIRegistry;
> ..
> protected SPIRegistry<AbstractCDKActivity> cdkActivityRegistry = new
> SPIRegistry<AbstractCDKActivity>(
>                       AbstractCDKActivity.class);
>
> ..
> for (AbstractCDKActivity cdkActivity : cdkActivityRegistry.getInstances()) {
>                 service = new CDKServiceDescriptor(cdkActivity.getClass());
>                 service.setActivityName(activity.getActivityName());
>                 service.setFolderName(activity.getFolderName());
>                 service.setDescription(activity.getDescription());
>
> service.setAdditionalProperties(activity.getAdditionalProperties());
>                 results.add(service);
> }
>
> If you go for this approach you would not need to use the package name
> restrictions or the context loader tricks. You would still need to
> sort something out about this service.setConfigurationPanelClass -
> which I guess has to do with finding the configuration panel for your
> activity.
>
> You could do a similar interface and SPI registry for finding the
> right ActivityConfigurationPanel - they would have to be
> instantiatable (is that a word?) with a default constructor, and some
> canHandle(AbstractCDKActivity activity) method which you check to be
> able to find the right panel. We would normally do this as a factory
> that could then return the ActivityConfigurationPanel.
>
> On the other hand I'm not sure why this would be needed, it seems to
> be because you have a common CDKContextualView which simply calls
> these panels - I would just avoid this indirection and additional SPI
> by having several contextual views and configuration actions, one
> could say it handles activities MDLSDFileWriterActivity,
> MDLMolFileWriterActivity, etc.  (or a common FileWriter interface?) -
> and another for the FileReader.
>
>
> These are just my suggestions, to get it working inside the plugin all
> I believe you will need to do is set the Thread contextual view using
> Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
>
> .. I tested this for your code, and it seems to work, except I got
> this exception:
>
> org.openscience.cdk.applications.taverna.ui.serviceprovider.CDKServiceProvider
> java.lang.ClassNotFoundException:
> org.openscience.cdk.applications.taverna.ui.serviceprovider.CDKServiceProvider
>       at 
> net.sf.taverna.raven.repository.impl.LocalArtifactClassLoader.findClass(LocalArtifactClassLoader.java:343)
>       at 
> net.sf.taverna.raven.repository.impl.LocalArtifactClassLoader.findClass(LocalArtifactClassLoader.java:276)
>       at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
>       at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
>       at java.lang.Class.forName0(Native Method)
>       at java.lang.Class.forName(Class.java:169)
>       at 
> org.openscience.cdk.applications.taverna.CDKClassGrabber.getClassesForPackage(CDKClassGrabber.java:68)
>       at 
> org.openscience.cdk.applications.taverna.CDKClassGrabber.getClassessOfSuperclass(CDKClassGrabber.java:92)
>       at 
> org.openscience.cdk.applications.taverna.ui.serviceprovider.CDKServiceProvider.findServiceDescriptionsAsync(CDKServiceProvider.java:29)
>       at 
> net.sf.taverna.t2.servicedescriptions.impl.ServiceDescriptionRegistryImpl$FindServiceDescriptionsThread.run(ServiceDescriptionRegistryImpl.java:502)
>
> Here, and a few other places you are using Java's Class.forName() when
> loading a class, which tries to find the class loader via a hack of
> looking in the stack to find what is the calling class's classLoader,
> in this case it will be cdk-taverna-2-activity and not
> cdk-taverna-2-activity-ui where
> org.openscience.cdk.applications.taverna.ui.serviceprovider.CDKServiceProvider
> lives. Remember that inside Raven cdk-taverna-2-activity can't see
> cdk-taverna-2-activity-ui. (In this case you don't actually need
> CDKServiceProvider - but your method is looking up ALL classes of the
> given package name - another good hint to rather go for a more normal
> SPI approach)
>
> You will need to use the correct classloader, ie. the one where you
> found the class (or SPI file). So try using cld.loadClass(className)
> instead.
>
>   


------------------------------------------------------------------------------

_______________________________________________
taverna-hackers mailing list
[email protected]
Web site: http://www.taverna.org.uk
Mailing lists: http://www.taverna.org.uk/about/contact-us/
Developers Guide: http://www.taverna.org.uk/developers/

Reply via email to