samedi 6 juillet 2019

Dynamically load plugins with different versions of the plugin interface in Scala

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