• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

Plugin autoloading

 
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Does anyone know a simple way to search all the classes, in the classpath, that implements an interface.

I need it to develop a plugin autoloading system.

Any ideas. Thanks.
 
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No, you can't do that. However, you could do something else. You could make all of your plugins declare themselves in a file located on the classpath at /META-INF/plugin.xml (or whatever). Then, at runtime, you look for ALL classpath resources with that name and load your plugins. The problem with that is that all of your plugins would have to be in different jar files or at different base directories on your classpath. This idea comes from HiveMind (http://jakarta.apache.org/hivemind/index.html) which does something similar to dynamically load "module descriptors."
 
author and iconoclast
Posts: 24204
44
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

Welcome to JavaRanch!

In the most general case, this is complicated. For example, a custom class loader might be installed, and it may not be possible to find out what classpath that custom class loader will search.

But despite what James says, if the standard class loader is in place, then doing what you want is relatively straightforward. The standard classloader uses the system property java.class.path to hold the classpath. So you can simply get the value of this property, split it into tokens using java.io.File.pathSeparator, and then, for each token:

1) If it's a directory, use the "listFiles" method of the java.io.File class to search for .class files, load them using Class.forName(), and then check the Class object for the interfaces it implements; or

2) If it's a JAR file, then use the java.util.zip package to open the file, search for .class file entries, and again, load the classes and ask each Class for the interfaces it implements.

This might sound like a lot of work, but it's really not so bad. The more you know about the structure of your plugins (always in a JAR, never in a JAR, etc) the easier you can make it.
 
(instanceof Sidekick)
Posts: 8791
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Eclipse does something similar to what James described. It lists all the sub-directories off the plugins directory looking for "plugin.xml". When it finds one, it uses the properties in that file to load a plugin. So installing a new one is as easy as copying in a sub-directory, and removing one is as easy as deleting it. Nice & easy.
 
James Carman
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:
Hi,

Welcome to JavaRanch!

In the most general case, this is complicated. For example, a custom class loader might be installed, and it may not be possible to find out what classpath that custom class loader will search.

But despite what James says, if the standard class loader is in place, then doing what you want is relatively straightforward. The standard classloader uses the system property java.class.path to hold the classpath. So you can simply get the value of this property, split it into tokens using java.io.File.pathSeparator, and then, for each token:

1) If it's a directory, use the "listFiles" method of the java.io.File class to search for .class files, load them using Class.forName(), and then check the Class object for the interfaces it implements; or

2) If it's a JAR file, then use the java.util.zip package to open the file, search for .class file entries, and again, load the classes and ask each Class for the interfaces it implements.

This might sound like a lot of work, but it's really not so bad. The more you know about the structure of your plugins (always in a JAR, never in a JAR, etc) the easier you can make it.



Ahh, I was not aware of that. However, I thought they wanted a purely API-based approach. Which "standard classloader" are you talking about, so that I may inspect the code to learn more?
 
Juan Fco. S.
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I gave a try to the "META-INF/plugin.xml (getResources())" solution, and it worked very well. Now I only have to put my_plugin.jar in the classpath and everything is automated.

Thanks a lot.
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24204
44
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by James Carman:


Ahh, I was not aware of that. However, I thought they wanted a purely API-based approach. Which "standard classloader" are you talking about, so that I may inspect the code to learn more?



Ted Neward's brilliant paper on this is here. Everything you ever wanted or needed to know about class loading is in there.
 
James Carman
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm fairly familiar with classloading in general. I just didn't know about that standard system property. I don't know how well that will work inside an web application server, though. The system property wouldn't change from webapp to webapp, but different webapps must have different classpaths. That system property only contains the classpath used (bootstrap and all) to start the JVM, correct? So, your solution would work for a stand-alone application just fine, provided you have access to those system properties, have access to the files in those directories, and are not using any custom classloaders (if you were, you'd probably know where the files were anyway). My solution, while not allowing them to "search" the classpath, is more portable to different situations, but does require that you declare which plugins are on the classpath and where.
 
James Carman
Ranch Hand
Posts: 580
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Juan Fco. S.:
I gave a try to the "META-INF/plugin.xml (getResources())" solution, and it worked very well. Now I only have to put my_plugin.jar in the classpath and everything is automated.

Thanks a lot.



Glad to hear it. If you want that stuff automated for you (along with quite a few other nice features), you might want to checkout HiveMind sometime. It's quite nice.
 
BWA HA HA HA HA HA HA! Tiny ad:
Free, earth friendly heat - from the CodeRanch trailboss
https://www.kickstarter.com/projects/paulwheaton/free-heat
reply
    Bookmark Topic Watch Topic
  • New Topic