首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有办法在不更新主应用程序的情况下更新模块库?

有没有办法在不更新主应用程序的情况下更新模块库?
EN

Stack Overflow用户
提问于 2019-05-16 21:12:02
回答 1查看 101关注 0票数 0

在模块化应用程序组织之前,我有一个加载自定义的主JavaFX应用程序,它为主应用程序中的不同选项和可能性创建了多个库。

在旧的实现方式中,我只是发送新的库来更新,主应用程序从文件夹中读取所有库,它的工作方式就像一个护身符。但是在模块化系统中,如果我的应用程序想要使用我发送的新模块库,它需要更新它的module-info文件,我需要发送模块库和主应用程序的更新。想象一下,这就像是,chrome需要为创建的每个新插件发送浏览器更新。正如我所看到的,使用Java模块化系统,您不能创建模块化应用程序。

有没有办法在不更新主应用程序的情况下导入新的模块?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-17 21:50:24

Java有一个这样的类:ServiceLoader

如果我们假设您有一个名为PluginProvider的“服务提供者”接口,其他模块可以通过将以下内容放入其各自的module-info.java描述符中来声明自己提供该服务:

代码语言:javascript
复制
provides com.john.myapp.PluginProvider with com.library.MyProvider;

然后,您的应用程序将声明它在自己的module-info中使用该服务:

代码语言:javascript
复制
uses com.john.myapp.PluginProvider;

您的应用程序代码将创建一个ModuleFinder来查找您期望这些插件模块所在的目录,然后将该ModuleFinder传递给一个Configuration,该ModuleLayer可用于为ServiceLoader创建一个ModuleLayer

代码语言:javascript
复制
public class PluginLoader {

    private final ServiceLoader<PluginProvider> loader;

    public PluginLoader() {

        Path pluginDir = Paths.get(System.getProperty("user.home"),
            ".local", "share", "MyApplication", "plugins");

        ModuleLayer layer = PluginProvider.class.getModule().getLayer();
        layer = layer.defineModulesWithOneLoader(
            layer.configuration().resolveAndBind(
                ModuleFinder.of(),
                ModuleFinder.of(pluginDir),
                Collections.emptySet()),
            PluginProvider.class.getClassLoader());

        loader = ServiceLoader.load(layer, PluginProvider.class);
    }

    public Stream<PluginProvider> getAll() {
        return loader.stream();
    }

    public void reload() {
        loader.reload();
    }
}

您甚至可能希望为新的或删除的文件watch插件目录:

代码语言:javascript
复制
try (WatchService watch = pluginDir.getFileSystem().newWatchService()) {

    pluginDir.register(watch,
        StandardWatchEventKinds.ENTRY_CREATE,
        StandardWatchEventKinds.ENTRY_DELETE,
        StandardWatchEventKinds.ENTRY_MODIFY,
        StandardWatchEventKinds.OVERFLOW);

    WatchKey key;
    while ((key = watch.take()).isValid()) {
        loader.reload();
        key.reset();
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56169439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档