[英]Implementing dynamic plugins in Java
I'd like to implement a dynamic plugin feature in a Java application. 我想在Java应用程序中实现动态插件功能。 Ideally:
理想的情况是:
Plugin
with a method like getCapabilities()
. getCapabilities()
等方法定义接口Plugin
。 pluginX.jar
containing a class PluginXImpl
implementing Plugin
(and maybe some others). pluginX.jar
含有类PluginXImpl
实现Plugin
(也许有些人)。 pluginX.jar
in a special directory or set a configuration parameter pointing to it. pluginX.jar
放在特殊目录中或设置指向它的配置参数。 The user should not necessarily have to include pluginX.jar
in their classpath. pluginX.jar
。 PluginXImpl
(maybe via the JAR manifest, maybe by reflection) and add it to a registry. PluginXImpl
(可能通过JAR清单,可能通过反射)并将其添加到注册表。 PluginXImpl
, eg, by invoking a method like getPluginWithCapabilities("X")
. PluginXImpl
的实例,例如,通过调用getPluginWithCapabilities("X")
。 The user should not necessarily have to know the name of the plugin. I've got a sense I should be able to do this with peaberry , but I can't make any sense of the documentation. 我有一种感觉,我应该能够用peaberry做到这一点,但我无法理解文档。 I've invested some time in learning Guice, so my preferred answer would not be "use Spring Dynamic Modules ."
我花了一些时间学习Guice,所以我的首选答案不是“使用Spring Dynamic Modules” 。
Can anybody give me a simple idea of how to go about doing this using Guice/peaberry, OSGi, or just plain Java? 任何人都可以给我一个简单的想法,如何使用Guice / peaberry,OSGi,或只是简单的Java?
This is actually quite easy using plain Java means: 使用普通Java意味着这很简单:
Since you don't want the user to configure the classpath before starting the application, I would first create a URLClassLoader with an array of URLs to the files in your plugin directory. 由于您不希望用户在启动应用程序之前配置类路径,因此我首先要创建一个URLClassLoader,其中包含插件目录中文件的URL数组。 Use File.listFiles to find all plugin jars and then File.toURI().toURL() to get a URL to each file.
使用File.listFiles查找所有插件jar,然后使用File.toURI()。toURL()获取每个文件的URL。 You should pass the system classloader (ClassLoader.getSystemClassLoader()) as a parent to your URLClassLoader.
您应该将系统类加载器(ClassLoader.getSystemClassLoader())作为父类传递给URLClassLoader。
If the plugin jars contain a configuration file in META-INF/services as described in the API documentation for java.util.ServiceLoader, you can now use ServiceLoader.load(Plugin.class, myUrlClassLoader) to obatin a service loader for your Plugin interface and call iterator() on it to get instances of all configured Plugin implementations. 如果插件jar包含META-INF / services中的配置文件,如java.util.ServiceLoader的API文档中所述,您现在可以使用ServiceLoader.load(Plugin.class,myUrlClassLoader)来获取插件接口的服务加载器并在其上调用iterator()以获取所有已配置的插件实现的实例。
You still have to provide your own wrapper around this to filter plugin capabilites, but that shouldn't be too much trouble, I suppose. 你仍然需要提供你自己的包装来过滤插件功能,但我认为这应该不会太麻烦。
OSGI would be fine if you want to replace the plugins during runtime ig for bugfixes in a 24/7 environment. 如果你想在24/7环境中的错误修正的运行时ig期间替换插件,OSGI会没问题。 I played a while with OSGI but it took too much time, because it wasn't a requirement, and you need a plan b if you remove a bundle.
我和OSGI玩了一段时间,但花了太多时间,因为这不是一个要求,如果你删除一个捆绑,你需要一个计划b。
My humble solution then was, providing a properties files with the class names of plugin descriptor classes and let the server call them to register (including quering their capabilities). 我的谦虚解决方案是,提供一个包含插件描述符类的类名的属性文件,让服务器调用它们进行注册(包括查询它们的功能)。
This is obvious suboptimal but I can't wait to read the accepted answer. 这显然不是最理想的,但我迫不及待地想要阅读已接受的答案。
您是否有机会利用服务提供商界面 ?
The best way to implement plug-ins with Guice is with Multibindings . 使用Guice实现插件的最佳方法是使用Multibindings 。 The linked page goes into detail on how to use multibindings to host plugins.
链接页面详细介绍了如何使用多重绑定来托管插件。
Apologize if you know this, but check out the forName
method of Class . 如果您知道这一点,请道歉,但请查看Class的
forName
方法。 It is used at least in JDBC to dynamically load the DBMS-specific driver classes runtime by class name. 它至少在JDBC中用于按类名动态加载特定于DBMS的驱动程序类运行时。
Then I guess it would not be difficult to enumerate all class/jar files in a directory, load each of them, and define an interface for a static method getCapabilities()
(or any name you choose) that returns their capabilities/description in whatever terms and format that makes sense for your system. 然后我想枚举目录中的所有类/ jar文件,加载每个文件并定义一个静态方法
getCapabilities()
(或你选择的任何名称getCapabilities()
的接口并不困难,它返回它们的功能/描述。对您的系统有意义的术语和格式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.