I have an application that loads plugins from external jar files, and so far I have only had one version of the plugin interface, however, now I need to add in a new function in the interface, but I still want to support the old plugins.
I cannot find out how i detect which version of my plugin interface the jar implements and then also how to instantiate the correct version?
My current plugin loader (simplified) looks like this:
def init(pluginPath: String): Unit = {
val dir = new File(pluginPath)
if (dir.exists && dir.isDirectory) {
val jarFiles = dir.listFiles().filter(file => file.isFile && file.getName.endsWith(".jar"))
jarFiles.foreach(jarFile => {
println(s"File: ${jarFile.getName}")
// Jar manifest info
val mainAttr = (new JarFile(jarFile)).getManifest.getMainAttributes
val implTitle = mainAttr.getValue("Implementation-Title")
val implVersion = mainAttr.getValue("Implementation-Version")
println(s"=== ${implTitle} - ${implVersion} ===")
// Reflection
val finder = ClassFinder(Seq(jarFile))
val classes = finder.getClasses()
val classMap = ClassFinder.classInfoMap(classes)
// Plugins
val plugins = ClassFinder.concreteSubclasses("org.example.shared.plugin", classMap)
// Class loader
val classLoader = new URLClassLoader(Seq(jarFile.toURI.toURL), getClass.getClassLoader)
plugins.foreach(pluginString => {
val plugin = classLoader.loadClass(pluginString.name).newInstance().asInstanceOf[plugin]
println(s"Name: ${pluginString.name}")
println(s"Plugin: ${plugin.getSchema}")
})
})
} else {
println(s"Could not load from path: ${pluginPath}")
}
}
I am working with an assumption, that my plugin needs to extend a simple trait trait plugin extends pluginBase { ... }
such that i can find and instantiate them from different jars also, but how to tie it all together.
Any suggestion on what i can look at for do for this?
Thanks.
Aucun commentaire:
Enregistrer un commentaire