动态加载 jar 并在其中执行任意代码
我正在编写一个 java 控制台应用程序,我希望人们能够为其编写插件,然后将这些插件作为 jar 分发。我希望用户能够将插件(jar)放入“插件”文件夹中,重新启动应用程序,然后加载并运行插件。我不希望用户必须指定要为插件或类似内容执行的类/方法。
我可以使用通配符类路径将 jar 加载到“plugins”目录,但我需要某种方式让这些插件通过运行每个插件都需要的 register()
方法来向应用程序注册自己定义某处。插件(jar)如何指定其 register()
方法的定义位置(包和类),以便我的应用程序知道调用它?
我意识到 OSGi 可以完成此任务,但这是一个相当小的应用程序,如果存在更简单的解决方案,我宁愿不使用 OSGi。
背景:
这些插件注册来自它们想要处理的应用程序的事件。用户将能够在每个插件的基础上禁用特定事件的处理,因此这些插件的配置将存储在应用程序的数据库中。当插件注册自身时,应用程序将检查数据库以查看该插件是否存在配置,如果不存在,它将在数据库中为其创建新的默认配置。
I have a java console app that I'm writing, and I want people to be able to write plugins for it and then to distribute those plugins as jars. I want users to be able to drop a plugin (jar) into a "plugins" folder, restart the app, and have the plugin loaded and running. I don't want the user to have to specify a class/method to execute for the plugin or anything like that.
I can load the jars with a wildcard classpath to the "plugins" directory, but I need some way for those plugins to register themselves with the application by running a register()
method that each plugin will need to define somewhere. How can the plugin (jar) specify where(package and class) it's register()
method is defined so my app will know to call it?
I realize that OSGi can accomplish this, but this is a fairly small application and I would prefer not to use OSGi if a simpler solution exists.
Background:
These plugins register events from the app that they want to handle. The user will be able to disable the handling of specific events on a per plugin basis, so the configuration for these plugins will be stored in the app's database. When a plugin registers itself, the app will check the database to see if a configuration exists for that plugin, and if not it will create a new default configuration for it in the database.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为您的应用程序定义一个清单文件来标准化此行为。您可以将其实现为属性文件、XML 或您选择的任何格式。清单文件将包含标准属性名称,其值为插件的“启动类”。让用户从您定义的接口或抽象类扩展此启动类,以便您可以强制执行预期的行为(也称为“注册”方法)。
然后,最终用户将其类文件和清单捆绑到 JAR 中,并将其分发到应用程序的插件文件夹中。
OSGI 绝对适合这个,你看过 Concierge 吗?它的部署尺寸小得离谱。
Define a manifest file for your application that standardizes this behaviour. You could implement it as a property file, XML, or whatever format you chose. The manifest file would contain a standard property name, with the value being the 'startup class' for the plugin. Have the users extend this startup class from an interface or abstract class you define, so that you can enforce expected behaviour (aka, have a 'register' method).
The end user then bundles their class files and the manifest into a JAR and distributes it in the plug-in folder of your application.
OSGI is definitely a good fit for this, have you looked at Concierge? It's ridiculously small in deployed size.
想必您的注册方法是插件接口的一部分?
如果是这样,您可以实现自定义类加载器来检测实现此接口的类。然后使用基于侦听器的方法来通知管理类存在的插件的任何对象。
Presumably your register method is part of a Plugin interface?
If so you could implement a custom ClassLoader to detect classes implementing this interface. Then subsequently use a Listener based approach to notifying whatever object manages your plugins of the classes' presence.
还有另一个线程,您可能会发现它很有帮助
我应该如何动态加载 Jars在运行时?
还可以尝试查看 Jar 类加载器
There is another thread, which you may find helpful
How should I load Jars dynamically at runtime?
Also try looking into Jar class loader