JARPluginLoader.scala 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. This file is part of karl-marx.
  3. karl-marx is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. karl-marx is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with karl-marx. If not, see <https://www.gnu.org/licenses/>.
  13. */
  14. package org.congressodeiradicali.karlmarx
  15. import java.io.File
  16. import java.net.URL
  17. import java.util.Properties
  18. import java.util.jar.JarFile
  19. import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader
  20. import scala.util.{Failure, Success, Try}
  21. class JARPluginLoader extends PluginLoader {
  22. final val MANIFEST_LOCATION = "plugin-manifest.properties"
  23. // manifest structure is
  24. // package=some.package
  25. // class=PluginClassName
  26. override def loadFromFile(file: File): Try[Plugin] = {
  27. val jarFile = new JarFile(file)
  28. val manifestInputStream = jarFile.getInputStream(jarFile.getEntry(MANIFEST_LOCATION))
  29. val props = new Properties()
  30. props.load(manifestInputStream)
  31. manifestInputStream.close()
  32. val `package` = props.getProperty("package")
  33. val `class` = props.getProperty("class")
  34. val fullClassName = s"${`package`}.${`class`}"
  35. try {
  36. val url = file.toURI.toURL
  37. val jarUrl = s"jar:${url.toString}!/"
  38. val urls = Seq[URL](new URL(jarUrl))
  39. val ucl = new URLClassLoader(urls, null)
  40. // TODO deprecation
  41. val plugin = Class.forName(fullClassName, true, ucl).newInstance().asInstanceOf[Plugin]
  42. Success(plugin)
  43. } catch {
  44. case e: Throwable => Failure(e)
  45. }
  46. }
  47. }