14

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

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

有相当于--add-modulesinMANIFEST.MF吗?还是有其他与 Java 8 兼容的解决方案?

4

3 回答 3

9

不幸的是,没有--add-modulesin 的等价物MANIFEST.MF。但是,您可以module-info.java在那里创建和声明您的依赖项:

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

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

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

  • 编译所有类module-info.java,除了javac --release 8
  • module-info.java用编译javac --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.class此外,您可以只放入META-INF文件夹。这将具有相同的效果。但是,这可能不适用于某些工具和平台。所以我认为第一种方式更可取。

于 2017-04-25T09:49:33.357 回答
5

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

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

Java 8 和 9

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

它会解决你的问题吗?

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

全模块化

如果您的模块用于模块路径,可访问性规则确保:

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

这表示:

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

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

于 2017-04-27T07:00:53.247 回答
4

可能是 Jigsaw 的最后几分钟会有需要的 manifest 参数。缺点,它只适用于主 jar 文件。

样本:

添加-导出:java.base/java.lang java.base/java.lang.invoke

或者

添加-导出-私有:java.base/java.lang java.base/java.lang.invoke

http://openjdk.java.net/projects/jigsaw/spec/issues/#AddExportsInManifest http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-September/000391.html

于 2017-05-27T10:22:51.437 回答