我可以通过MANIFEST需要Java 9模块吗?中频?

我的 Java 库应该与 Java 8 和 Java 9 兼容。为了与Java 9一起运行,我们需要一些Java 9模块。

我知道我可以通过命令行添加它。但它是一个库,我无法控制命令行。--add-modules

是否存在等效于 in ?或者有没有其他与Java 8兼容的解决方案?--add-modulesMANIFEST.MF


答案 1

遗憾的是,没有 等效的 中。但是,您可以在此处创建和声明依赖项:--add-modulesMANIFEST.MFmodule-info.java

module <module-name> {
    requires <dependency>;
    ...
}

但是,如果您编译并简单地放入JAR,则它可能在某些平台(例如Android)上不起作用。那么该怎么办呢?Java 9 中有一个新功能:多版本 JAR 文件 (JEP 238)。这个想法是,你可以把Java 9类文件放到一个特殊的目录()上,Java 9会正确地处理它们(而Java 8会忽略它们)。module-info.javamodule-info.classMETA-INF/version/9/

因此,这些是您应该执行的步骤:

  • 编译除module-info.javajavac --release 8
  • 使用 编译。module-info.javajavac --release 9
  • 构建一个 JAR 文件,使其具有以下结构:
JAR root
  - A.class
  - B.class
  - C.class
   ...
  - META-INF
    - versions
      - 9
        - module-info.class

生成的 JAR 应与 Java 8 和 Java 9 兼容。

另外,您可以直接放入文件夹。这将具有相同的效果。但是,这可能不适用于某些工具和平台。所以我认为第一种方法更可取。module-info.classMETA-INF


答案 2

模块在其模块声明中表达依赖关系,因此您必须创建一个 ,定义模块的名称,依赖项(在您的情况下为 和 )和导出(稍后会详细介绍)。module-info.javarequires java.activationrequires java.xml.bind

模块声明必须由 Java 9 编译器编译,以创建属于 JAR 根文件夹的模块描述符。module-info.class

Java 8 和 9

9 之前的 Java 版本将忽略 ,这意味着如果您为 Java 8 编译其余代码(通过使用或使用 new 标志),您的库仍然可以在该版本上运行。module-info.classjavac 8--releasejavac 9

它会解决你的问题吗?

即使是Java 9,也只有在JAR最终出现在模块路径上时才会将其作为模块进行处理。只有这样,它才能看到子句,并在模块图中包含您正在使用的 Java EE 模块。这意味着在 Java 9 的类路径上使用库的客户端仍然必须通过命令行手动添加两个模块。requires

全模块化

如果在模块路径上使用模块,则辅助功能规则可确保:

  1. 客户端只能在导出的包中使用公共类型(在编译时和运行时)
  2. 您的代码只能看到您依赖的模块

这意味着:

  1. 必须在模块声明中包含导出
  2. 您必须声明所有依赖项,而不仅仅是两个 JDK 模块

特别是第二点,如果你依赖于尚未模块化的项目,那么第二点可能很困难,但这是另一个问题。


推荐