使用Java构建插件系统的最佳方法

156

如何为您的Java应用程序实现插件系统?

是否可以有一个易于使用(对于开发人员)的系统,以实现以下功能:

  • 用户将其插件放入应用程序的子目录中
  • 插件可以提供配置界面
  • 如果使用框架,则许可证是否与商业开发兼容?
8个回答

116

首先,您需要一个所有插件都需要实现的接口,例如:

public interface Plugin {
    public void load(PluginConfiguration pluginConfiguration);
    public void run();
    public void unload();
    public JComponent getConfigurationPage();
}

插件作者应该将他们的插件打包为JAR文件。您的应用程序打开JAR文件,然后可以使用JAR清单中的属性或JAR文件中所有文件的列表来查找实现您的Plugin接口的类。实例化该类,插件即可使用。

当然,您还可能希望实现某种沙箱机制,以限制插件能够进行的操作。我创建了一个小的测试应用程序(并在博客中介绍),其中包含两个插件,其中一个被拒绝访问本地资源。


2
你提到的沙盒实际上是最困难的部分!但不要担心 - 如上所述,OSGi已经为您完成了它。 - Chii
1
沙箱并不难。花了我大约两周的时间才找到正确的方法,但一旦你知道了,它就非常简单。 :) - Bombe
抱歉Bombe,我几天前尝试过,但它一直超时 - 现在两个链接都可以使用了。感谢您提供的示例 :) - ataulm
@Bombe 你说的load()和unload()是什么意思? - capovawi
@capovawi 我并没有别的意思。如果你不需要那些方法,就不要在你的插件接口中包含它们。 - Bombe
显示剩余4条评论

43

使用 OSGi

它是Eclipse插件系统的基础。 Equinox 是Eclipse的实现(以EPL许可证授权),而Felix是Apache项目的实现(以Apache Public License许可证授权)。

Eclipse提供了一个具体的例子,表明OSGi可以覆盖您所提到的点(或者如果您想要完整的Eclipse / SWT / JFace堆栈,可以在其上构建应用程序 Eclipse RCP)。


4
我曾涉猎过OSGi,但从未找到一个真正好的入门指南。如果有人可以在这里推荐一些链接,那就太棒了。 - Brian Matthews
1
我已将Equinox嵌入我的应用程序,并使用标准的OSGi实践来完全满足OP的要求。在Swing中,而不是SWT。也可以进行Web启动。良好的起始资源: http://neilbartlett.name/blog/ - basszero
4
OSGi 理想情况下是事实上的插件系统。然而,从标准 Java 到 OSGi 编程模型的转变相当大... - Hendy Irawan

31
自Java 1.6起,就有了java.util.ServiceLoader,可用于编写自己的简单系统。但如果需要更多功能,请使用现有框架。

20

使用PF4J。 它支持Web、Spring和Wicket。 易于使用和构建应用程序。


我发现这正是我所需要的,而且它似乎相当简单,但我需要一些帮助。 - nonybrighto
尝试在 GitHub 上向 Decebal 提出问题,他会帮助你。 - Daniel Jipa
请查看此处有关Decebal账户状态的信息:https://meta.stackoverflow.com/questions/376686/cant-there-be-a-direct-lift-of-the-ban-or-the-option-to-specifically-answer-onl - Wolfgang Fahl
1
如果你正在关注pf4j,那么你也可以看一下https://github.com/hank-cp/sbp。它是基于pf4j构建的,支持Spring Boot构建完整的Web应用程序。 - Hank

17

这里有人用过JPF吗?听起来很有趣。 - Sven Lilienthal
1
JabRef使用JPF作为其插件。效果相当不错。 - koppor
我正在使用JPF,但它与Ant紧密耦合。我想摆脱它,但我不知道这会对我的应用程序产生多大的影响。 - MartinL
我为一个开源产品(OpenEMM)创建了一个 JPF 插件;我使用 maven(maven-assembly 插件)成功地完成了它;毫无疑问,我非常欣赏这种简单的开发方式,即使现在 OSGI 可能更受欢迎。 - рüффп
使用JPF是否有Java版本限制? - Madhav

15

我花了一周时间学习OSGi-一周的紧张,全身心投入到OSGi中。最后感觉像是一场噩梦,但我学到了很多。

我成功地让OSGi运行起来了(不容易,所有的示例都已过时,网上的一切都至少有三年甚至五年),但我在将它集成到现有项目中遇到了严重的问题,因为JAR清单存在问题。

简言之,只有一些晦涩难懂的工具用于构建清单,并且它们没有很好的文档(BND Tools并不算晦涩,但它是为Eclipse中的某个特定流程而设计的)。此外,大多数可用的OSGi信息并不面向那些拥有现有桌面应用程序的应用开发人员。

这使得大量的信息背景模糊或不适当。Neil Bartlett的博客文章帮助最大,但即使那些也无法获得一个工作系统(我从Felix教程中获取了一些代码并将其组合在一起以获取嵌入式框架滚动)。我找到了他多年前免费发布的书稿,非常优秀,但Eclipse OSGi支持的更改导致Eclipse中的示例代码不起作用。


20
这怎么算是回答呢?它更像是在抱怨OSGi,而且你甚至没有解释OSGi是什么。 - Stealth Rabbi
2
@StealthRabbi 在这个“答案”发布时以及之后的一段时间内,对于那些试图在野外使用OSGi的人来说,这是有用的信息。OSGi已经成为了讨论的一部分,因此没有必要对其进行定义。它是一个答案,因为它可能会节省人们一周的工作时间——这也是SO存在的原因。 - Sean Anderson

11

我认为推荐OSGi来解决上述问题是极其不合适的建议。OSGi确实是“正确的选择”,但对于像上述场景这样的情况,我认为JPF或某些自己开发的最小化框架已经足够了。


3
多年前,我开始了一个类似的项目,并希望很快就能完成。我受到NetBeans和Eclipse等项目的启发,但同时也有所不同。OSGi现在看起来是一个不错的选择,但我没有机会将其与我的项目进行比较。它与上面提到的JPF相似,但同时在许多方面也有所不同。
我的基本想法是尽可能地简化构建Java应用程序,没有Web应用程序、桌面应用程序或Applet/JWS应用程序之间的分离(当然这不包括UI - 还没有)。作为核心功能。
我建立这个项目时有几个目标:
- 不管你是构建Web应用程序还是桌面应用程序,你都应该以相同的方式启动应用程序,即一个普通的main方法,没有花哨的web.xml声明(并不是说我反对有一个标准的Web描述符,但它与插件系统不太匹配,在那里你可以根据自己的意愿添加“servlets” - 我称之为RequestHandler(s))。 - 易于在“扩展点”周围插入“扩展” - 来自Eclipse的东西,但是采用了不同的方法。 - 自我部署,由于所有插件都已注册(XML文件),因此应用程序必须是自我部署的,独立于构建系统 - 当然有一个Ant任务和一个Maven MOJO,它们是与外部世界的链接,但最终它调用应用程序并指示其在特定位置自我部署。 - 借鉴了Maven的做法,可以从存储库(包括Maven 1和2存储库)下载代码,因此只要您可以访问存储库,您的应用程序就可以部署为单个小jar文件(有时很有用),基本上这提供了对自动更新的支持 - 您是否喜欢通过Web应用程序被通知有新版本可用,并已下载并只需要您的许可安装?我知道我很喜欢这个想法)。 - 关于系统健康状况的基本应用程序监视,故障时的电子邮件通知。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接