背景

在Maven中,工件可以使用

<optional>true</optional>

这意味着该依赖性不是必需的,但可以使用(如果存在)。

The State of the Module System似乎指定一个模块只能读取其所需的模块。

问题
  • Java 9模块系统确实不支持可选依赖项吗?
  • 为什么不呢?
  • Java 9模块系统提供了哪些替代可选依赖项的方法?

  • 用例

    我有一个框架,该框架集成了应用程序可能使用或可能不使用的各种库。当前,该框架是单个JAR,可反射(reflect)类路径以跳过缺少库的集成代码。

    我想我们可以针对每种配置将其拆分为一个单独的模块,但这会导致JAR数量的爆炸性增长,因为我们不仅需要为每个可选依赖项使用一个单独的JAR,而且对于大多数对还需要一个单独的JAR可选依赖项...

    最佳答案

    是的,optional dependencies are supported。引用the original proposal:



    (同时,official documentation was created for that feature。)

    我为此写了a demo。有趣的花样是声明可选依赖项的模块的module-info.java ...

    module org.codefx.demo.advent {
        // list the required modules
        requires org.codefx.demo.advent.calendar;
        // with 'static' the factories are only required at compile time;
        // to be present at run time either other modules most require them
        // or they must be added with the '--add-modules' command line option
        requires static org.codefx.demo.advent.factory.chocolate;
        requires static org.codefx.demo.advent.factory.quote;
    }
    

    ...,以及同一模块中要从其可选依赖项访问类型的代码。它必须写成这样,如果不存在ChocolateFactory和/或QuoteFactory类型,它就会优雅地失败:
    private static List<SurpriseFactory> createSurpriseFactories() {
        return Stream.of(
                createChocolateFactoryIfAccessible(),
                createQuoteFactoryIfAccessible())
                .flatMap(Optional::stream)
                .collect(toList());
    }
    
    private static Optional<SurpriseFactory> createChocolateFactoryIfAccessible() {
        try {
            return Optional.of(new ChocolateFactory());
        } catch (NoClassDefFoundError er) {
            return Optional.empty();
        }
    }
    
    private static Optional<SurpriseFactory> createQuoteFactoryIfAccessible() {
        try {
            return Optional.of(new QuoteFactory());
        } catch (NoClassDefFoundError er) {
            return Optional.empty();
        }
    }
    

    最后,命令行可用于定义应用启动的模块:
    $java \
        --add-modules org.codefx.demo.advent.factory.chocolate,org.codefx.demo.advent.factory.quote \
        -p mods -m org.codefx.demo.advent
    

    当然,其他模块也可能非必需地要求它们,这迫使JVM将它们包括在模块图中。

    07-24 09:46
    查看更多