Get all the plugins that implement an interface

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Get all the plugins that implement an interface

jeannot
Hi everyone,
I'd like to have access to all the classes located in the imageJ
plugin folder (including classes that are in a .jar file), check if
they implement a certain interface, and be able to instantiate them,
without knowing the name of the class a priori.
I tried to use ij's classLoader ( ij.IJ.getClassLoader() ) but the
field "classes" is private (and i couldn't access it even using
reflection)

Thanks

Jean.
Reply | Threaded
Open this post in threaded view
|

Re: Get all the plugins that implement an interface

dscho
Hi Jean,

On Tue, 29 Nov 2011, Jean Ollion wrote:

> I'd like to have access to all the classes located in the imageJ
> plugin folder (including classes that are in a .jar file), check if
> they implement a certain interface, and be able to instantiate them,
> without knowing the name of the class a priori.
> I tried to use ij's classLoader ( ij.IJ.getClassLoader() ) but the
> field "classes" is private (and i couldn't access it even using
> reflection)

Theoretically you could do that by enumerating all .jar files and then
opening them in a JarInputStream, opening each class individually and
inspecting the interface.

I say theoretically because you will most likely run out of perm space if
you do that with any decent amount of classes (for example in Fiji, you
cannot load all classes, there are too many).

Now, I fear that this is an X-Y problem. That is a problem X where you ask
for a specific solution Y. If you explain what you want to do, not how,
there is a chance somebody can give you a hint how to solve this in a
better way. (For example, the service provider concept looks like it could
help you.)

Ciao,
Johannes
Reply | Threaded
Open this post in threaded view
|

Re: Get all the plugins that implement an interface

jeannot
Hi Johannes,
Thank you for answering. I'll try to be more precise.
Actually, what i'm trying to do is exactly what IJ does with plugins,
but with other interfaces: be able to run any class located in the
plugin folder if it implements a given interface.
In my case, when a class implements my interface, it also implements
the PlugIn interface, so i guess it's easier to re-use what IJ does
when it looks for the plugins. If i understood well, it looks for the
.class files in the plugin directory, and uses the plugin.config file
for the .jar and .zip.
Is it possible to re-use the list of plugins (.class + .class within
.jar that are listed in the plugin.config file)? Are they all loaded
in IJ's  classLoader?

Hope it's less specific..
Thanks
Jean

2011/11/29 Johannes Schindelin <[hidden email]>:

> Hi Jean,
>
> On Tue, 29 Nov 2011, Jean Ollion wrote:
>
>> I'd like to have access to all the classes located in the imageJ
>> plugin folder (including classes that are in a .jar file), check if
>> they implement a certain interface, and be able to instantiate them,
>> without knowing the name of the class a priori.
>> I tried to use ij's classLoader ( ij.IJ.getClassLoader() ) but the
>> field "classes" is private (and i couldn't access it even using
>> reflection)
>
> Theoretically you could do that by enumerating all .jar files and then
> opening them in a JarInputStream, opening each class individually and
> inspecting the interface.
>
> I say theoretically because you will most likely run out of perm space if
> you do that with any decent amount of classes (for example in Fiji, you
> cannot load all classes, there are too many).
>
> Now, I fear that this is an X-Y problem. That is a problem X where you ask
> for a specific solution Y. If you explain what you want to do, not how,
> there is a chance somebody can give you a hint how to solve this in a
> better way. (For example, the service provider concept looks like it could
> help you.)
>
> Ciao,
> Johannes
>
Reply | Threaded
Open this post in threaded view
|

Re: Get all the plugins that implement an interface

dscho
Hi Jean,

On Wed, 30 Nov 2011, Jean Ollion wrote:

> Actually, what i'm trying to do is exactly what IJ does with plugins,
> but with other interfaces: be able to run any class located in the
> plugin folder if it implements a given interface.

That's not what ImageJ does. It finds all the .class and .jar files in
plugins/ that have an underscore in their names. In case of .jar files, it
looks whether there is a plugins.config file in there. If not, it
enumerates all classes in that .jar file whose names contain underscores.

These classes are simply expected to implement either the PlugIn or
PlugInFilter interface (latter takes precedence if the class implements
both).

> Is it possible to re-use the list of plugins (.class + .class within
> .jar that are listed in the plugin.config file)?

Yes, you can enumerate the values of the HashMap returned by
Menus.getCommands(). They are strings saying which classes are associated
with menu entries (possiby suffixed by something like ("blabla") which
would get passed as that arg parameter to the plugin).

> Are they all loaded in IJ's  classLoader?

Yes. They have to be, since the Help>Refresh Menus action needs to throw
away the class loader and instantiate a new one, as there is no way in
Java to unload a class from a class loader.

Have you ever had a look at the service provider framework of Java6? Or
even better, at sezpoz? Both seem to me to be a viable method to enumerate
classes of a certain type. That's how ImageJ2 does it.

Ciao,
Johannes
Reply | Threaded
Open this post in threaded view
|

Re: Get all the plugins that implement an interface

jeannot
Hi Johannes

2011/11/30 Johannes Schindelin <[hidden email]>:

> Hi Jean,
>
> On Wed, 30 Nov 2011, Jean Ollion wrote:
>
>> Actually, what i'm trying to do is exactly what IJ does with plugins,
>> but with other interfaces: be able to run any class located in the
>> plugin folder if it implements a given interface.
>
> That's not what ImageJ does. It finds all the .class and .jar files in
> plugins/ that have an underscore in their names. In case of .jar files, it
> looks whether there is a plugins.config file in there. If not, it
> enumerates all classes in that .jar file whose names contain underscores.
>
> These classes are simply expected to implement either the PlugIn or
> PlugInFilter interface (latter takes precedence if the class implements
> both).
>
>> Is it possible to re-use the list of plugins (.class + .class within
>> .jar that are listed in the plugin.config file)?
>
> Yes, you can enumerate the values of the HashMap returned by
> Menus.getCommands(). They are strings saying which classes are associated
> with menu entries (possiby suffixed by something like ("blabla") which
> would get passed as that arg parameter to the plugin).
>
>> Are they all loaded in IJ's  classLoader?
>
> Yes. They have to be, since the Help>Refresh Menus action needs to throw
> away the class loader and instantiate a new one, as there is no way in
> Java to unload a class from a class loader.
>
It works fine thanks.

> Have you ever had a look at the service provider framework of Java6? Or
> even better, at sezpoz? Both seem to me to be a viable method to enumerate
> classes of a certain type. That's how ImageJ2 does it.

I'll have a look at it, thanks for the tip.
>
> Ciao,
> Johannes
Bye
Jean