如何从 Java 9+ 中的目录动态加载模块

2023-12-08

我一直在开发一个带有基于插件的系统的软件,用户可以在其中编写自己的插件。我对 JMPS 很陌生,但我想使用 JMPS 而不是 OSGi 来实现这一点。制作了一个单独的 API 模块,甚至创建了一个测试插件。

插件以文件名“someplugin.jar”存储在目录中。

如何在运行时加载所有这些 jar(它们都不是自动模块,而是带有 module-info.class 的明确定义的模块)?我想在运行时动态加载它们的原因是用户可以选择更改目录来搜索插件,并且无需重新启动应用程序即可更改它。


要动态加载模块,您需要定义一个新的ModuleLayer。新的模块层将继承引导层:

enter image description here

这意味着在引导层(主模块所在的位置)中,您不能直接引用插件层中的类。但是,您可以通过以下方式使用插件层services.

以下是您可以用作起点的代码:

Path pluginsDir = Paths.get("plugins"); // Directory with plugins JARs

// Search for plugins in the plugins directory
ModuleFinder pluginsFinder = ModuleFinder.of(pluginsDir);

// Find all names of all found plugin modules
List<String> plugins = pluginsFinder
        .findAll()
        .stream()
        .map(ModuleReference::descriptor)
        .map(ModuleDescriptor::name)
        .collect(Collectors.toList());

// Create configuration that will resolve plugin modules
// (verify that the graph of modules is correct)
Configuration pluginsConfiguration = ModuleLayer
        .boot()
        .configuration()
        .resolve(pluginsFinder, ModuleFinder.of(), plugins);

// Create a module layer for plugins
ModuleLayer layer = ModuleLayer
        .boot()
        .defineModulesWithOneLoader(pluginsConfiguration, ClassLoader.getSystemClassLoader());

// Now you can use the new module layer to find service implementations in it
List<Your Service Interface> services = ServiceLoader
        .load(layer, <Your Service Interface>.class)
        .stream()
        .map(Provider::get)
        .collect(Collectors.toList());

// Do something with `services`
...

模块层被认为是一个高级主题,但我并不认为它真的很困难。您需要理解的唯一关键点是模块层是继承的。这意味着从子层中,您只能引用父层的类,反之亦然。要执行相反的操作,您必须使用控制反转它是在Java模块系统中实现的ServiceLoader.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 Java 9+ 中的目录动态加载模块 的相关文章

  • Java中字符串中特殊字符的替换

    Java中如何替换字符串 E g String a adf sdf 如何替换和避免特殊字符 您可以删除除此之外的所有字符可打印的 ASCII 范围 http en wikipedia org wiki ASCII ASCII printab
  • Hibernate注解放置问题

    我有一个我认为很简单的问题 我见过两种方式的例子 问题是 为什么我不能将注释放在字段上 让我举一个例子 Entity Table name widget public class Widget private Integer id Id G
  • 在文本文件中写入多行(java)

    下面的代码是运行命令cmd并使用命令行的输出生成一个文本文件 下面的代码在 Eclipse 的输出窗口中显示了正确的信息 但在文本文件中只打印了最后一行 谁能帮我这个 import java io public class TextFile
  • 使用 JPA Criteria API 进行分页的总行数

    我正在系统中为实体实现 高级搜索 功能 以便用户可以使用该实体的属性上的多个条件 eq ne gt lt 等 来搜索该实体 我正在使用 JPA 的 Criteria API 动态生成 Criteria 查询 然后使用setFirstResu
  • 是什么决定了从 lambda 创建哪个函数式接口?

    请考虑这个例子 import java util function Consumer public class Example public static void main String args Example example new
  • SAML 服务提供商 Spring Security

    当使用预先配置的服务提供者元数据时 在 Spring Security 中 是否应该有 2 个用于扩展元数据委托的 bean 定义 一份用于 IDP 元数据 一份用于 SP 元数据
  • Android在排序列表时忽略大小写

    我有一个名为路径的列表 我目前正在使用以下代码对字符串进行排序 java util Collections sort path 这工作正常 它对我的 列表进行排序 但是它以不同的方式处理第一个字母的情况 即它用大写字母对列表进行排序 然后用
  • Hibernate.createBlob() 方法从 Hibernate 4.0.1 开始已弃用,并移至 Hibernate.getLobCreator(Session session).createBlob()

    Method Hibernate createBlob 已弃用自休眠4 0 1并搬到Hibernate getLobCreator Session session createBlob 任何解决方案我应该在方法内传递什么getLobCrea
  • Calendar.getInstance(TimeZone.getTimeZone("UTC")) 不返回 UTC 时间

    我对得到的结果真的很困惑Calendar getInstance TimeZone getTimeZone UTC 方法调用 它返回 IST 时间 这是我使用的代码 Calendar cal Two Calendar getInstance
  • 编辑文件名在 JComboBox 中的显示方式,同时保持对文件的访问

    我对 Java 很陌生 对堆栈溢出也很陌生 我正在尝试利用 JMF API 创建一个用 Java 编码的简单媒体播放器 到目前为止 我已经能够设置一个简单的队列 播放列表来使用JComboBox called playListHolder
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • 替换后增量

    我自己已经有一个问题了 但我想扩展它后增量示例 https stackoverflow com questions 51308967 post increment with example char a D int b 5 System o
  • HQL Hibernate 内连接

    我怎样才能在 Hibernate 中编写这个 SQL 查询 我想使用 Hibernate 来创建查询 而不是创建数据库 SELECT FROM Employee e INNER JOIN Team t ON e Id team t Id t
  • spring中如何使用jackson代替JdkSerializationRedisSerializer

    我在我的一个 Java 应用程序中使用 Redis 并且正在序列化要存储在 Redis 中的对象列表 但是 我注意到使用 RedisTemplate 会使用 JdkSerializationRedisSerializer 相反 我想使用 J
  • 具有特定参数的 Spring AOP 切入点

    我需要创建一个我觉得很难描述的方面 所以让我指出一下想法 com x y 包 或任何子包 中的任何方法 一个方法参数是接口 javax portlet PortletRequest 的实现 该方法中可能有更多参数 它们可以是任何顺序 我需要
  • 为什么这个作业不起作用?

    我有课Results which extends ArrayList
  • Trie 数据结构 - Java [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有任何库或文档 链接提供了在 java 中实现 Trie 数据结构的更多信息 任何帮助都会很棒 Thanks 你可以阅读Java特里树
  • ServletContainer 类未找到异常

    我无法再编译我的球衣项目 并且出现以下异常 GRAVE Servlet Project API threw load exception java lang ClassNotFoundException com sun jersey spi
  • 如何在 JFreeChart 中设置多个系列的线条粗细?

    我创建了很多图表 在他们每个人中我都需要打电话 renderer setSeriesStroke i new BasicStroke 2 0f 对于每个系列 renderer is chart getXYPlot getRenderer 我

随机推荐

  • 如何在 iOS 中计算 SHA-2(最好是 SHA 256 或 SHA 512)哈希值?

    安全服务 API 似乎不允许我直接计算哈希值 有很多公共领域和自由许可的版本可用 但如果可能的话 我宁愿使用系统库实现 数据可以通过 NSData 或普通指针访问 哈希的加密强度对我来说很重要 SHA 256 是可接受的最小哈希大小 这就是
  • 用于打印括号内整数的正则表达式

    第一次使用正则表达式 尽管 stackoverflow 中已经有很多例子 但无法让它工作 如何提取括号内字符串中的整数 Example dijdi d43 d5 55 43 32 dm dij 99 x 会回来 43 32 99 and 如
  • WPF:允许用户调整 RichTextBox 中图像的大小

    WPF 中的 RichTextBox 控件中是否有一种方法允许用户调整插入图像的大小 或者您是否必须为此设计自己的方法 我想要实现的目标如下所示 是写字板执行我想要的操作的屏幕截图 Notes 以纯文本形式读取 RTF 文件 我发现与图像大
  • Python:父子层次结构的组合

    对于子父关系表 csv 我尝试使用表中的所有数据收集可能的父子关系组合链 我正在尝试解决一个问题 如果存在多个子父级 参见第 3 行和第 4 行 则第二个子父级组合 第 4 行 不包含在迭代中 数据示例 孩子 父母 A B A C B D
  • 对 Android 库应用程序进行单元测试的最简单方法?

    抱歉 如果这是一个有点模糊的问题 但是我很难找到一个solid有关如何使用 Android 进行单元测试 隔离测试 的示例 这是我想要实现的目标的示例 Some class class Calculator public int Add i
  • 检测屏幕分辨率来加载替代 CSS 是个好主意吗?

    我与一位平面设计师合作 他一直希望制作大于我推荐的 960 像素的网站 我可以使用液体布局做一定量的工作 但我真的很喜欢能够加载不同的 CSS 以实现更大的分辨率 我用谷歌搜索并找到了下面的链接 但我担心我没有听到更多关于此的信息 这是一个
  • NSDate 一天的开始和一天的结束

    NSDate beginningOfDay NSDate date NSCalendar cal NSCalendar currentCalendar NSDateComponents components cal components N
  • 如何在android中使用Gson库解析json响应?

    我有 api 它的响应如下 0 serialize 1 login users token aaaaa message login successful 我如何使用 Gson 在 android 中解析它 创建一个 Json 的 pojo
  • 为什么 Tiles REGEXP 通配符定义会导致无尽的 jsp 包含错误

    我将tiles 2 2 2与Struts2 2 2 3一起使用 因为Struts2 Tiles插件相当旧 它的实现使用了许多Tiles已弃用的API 并且我想尝试REGEXP通配符 所以我在下面实现了我自己的监听器 我的TilesConta
  • 来自后台工作人员的文本框文本?

    我一直在试图弄清楚如何从后台工作人员中获取文本框的文本或其他属性 有人知道怎么做这个吗 我无法将其作为参数传递 因为它需要是实时的 谢谢您的帮助 我认为你只需要调用该属性 伪代码 private void bgw1 DoWork objec
  • 向订阅该主题的所有用户推送通知(使用 FCM Firebase 的登录用户除外)

    现在我有一个拥有一万多名成员的群组 并且我为一个群组创建了一个主题 通知主题 该群组中的所有用户都订阅了该主题 现在 在组内任何用户都可以添加图像 文件或视频等帖子 当用户添加帖子时 我需要向订阅该主题的所有用户发送通知 但除了一个之外 即
  • 如何检测 CMake 中的意外函数覆盖?

    我刚刚在我的 CMake 代码中发现了复制和粘贴错误 function name do something endfunction function name do something else endfunction 我已经多次复制 重命
  • SKLabelNode 将消失但仍然可点击

    我正在使用 SpriteKit 和 Swift 制作一个游戏 运行 Xcode 6 我有一个SKLabelNode 我们称之为myLabelNode对于这个例子 当我打电话时myLabelNode removeFromParent 它会像它
  • C# StreamReader 从标签输入文件?

    我一直在使用StreamReader inputFile代码来自ListBox它效果很好 但是 我想输入来自 txt文件到一个Label盒子代替 这可能吗 这是我尝试过的代码 它给了我一个错误描述 说明 Use of unassigned
  • 如何为 UIPageViewControllerDataSource 提供默认实现?

    我认为这个问题的答案通常会解决 Objective C 协议的问题 但这是我遇到的第一个问题 我希望在实施时使用这些方法UIPageViewControllerDataSourceWithConnections import UIKit p
  • 是否有*任何*情况下“for _ in [1,2,3]”根本不会循环?

    我正在编写一些代码并犯了一个错误 该错误简化为 func f gt Int for in 1 2 3 return 1 编译器向我显示一个错误 指出f缺少回报 这让我意识到我的错误 我忘记在周围放置一个 if 语句return 但后来我意识
  • python 多处理队列实现

    我无法理解如何将队列实现到下面的多处理示例中 基本上 我希望代码能够 1 产生2个进程 完成 2 将我的 id list 分成两部分 完成 3 让每个进程迭代列表 打印出每个项目 并且仅在完成列表后才关闭 我知道我必须实现某种类型的排队系统
  • 如何使用ajax从html获取数据并将数据传递到php

    您好 我很想知道如何将字符串从表单传递到 php 该 php 将测试其中是否有内容 然后使用此表单发布一条警报消息 尝试从中获取数据 然后显示它是否已通过正确 HTML 代码
  • 在 Android 中使用 NanoHTTPD

    我正在尝试使用 NanoHTTP 来提供 HTML 文件 然而 NanoHTTP 相对来说没有文档记录 而且我对 Android 还很陌生 我的问题是 我在哪里存储 html 文件 以及如何使用 NanoHTTP 提供它 答案很晚 但可能对
  • 如何从 Java 9+ 中的目录动态加载模块

    我一直在开发一个带有基于插件的系统的软件 用户可以在其中编写自己的插件 我对 JMPS 很陌生 但我想使用 JMPS 而不是 OSGi 来实现这一点 制作了一个单独的 API 模块 甚至创建了一个测试插件 插件以文件名 someplugin