我的 Java 库应该与 Java 8 和 Java 9 兼容。为了使用 Java 9 运行,我们需要一些 Java 9 模块。
我知道我可以通过命令行添加它--add-modules
。但它是一个库,我无法控制命令行。
有相当于--add-modules
inMANIFEST.MF
吗?还是有其他与 Java 8 兼容的解决方案?
我的 Java 库应该与 Java 8 和 Java 9 兼容。为了使用 Java 9 运行,我们需要一些 Java 9 模块。
我知道我可以通过命令行添加它--add-modules
。但它是一个库,我无法控制命令行。
有相当于--add-modules
inMANIFEST.MF
吗?还是有其他与 Java 8 兼容的解决方案?
不幸的是,没有--add-modules
in 的等价物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 root
- A.class
- B.class
- C.class
...
- META-INF
- versions
- 9
- module-info.class
生成的 JAR 应该与 Java 8 和 Java 9 兼容。
module-info.class
此外,您可以只放入META-INF
文件夹。这将具有相同的效果。但是,这可能不适用于某些工具和平台。所以我认为第一种方式更可取。
模块在其模块声明中表达依赖关系,因此您必须创建一个module-info.java
,定义模块的名称、依赖关系(在您的情况下使用requires java.activation
and requires java.xml.bind
)和导出(稍后会详细介绍)。
模块声明必须由 Java 9 编译器编译,以创建module-info.class
属于 JAR 根文件夹的模块描述符。
9 之前的 Java 版本将忽略module-info.class
,这意味着如果您为 Java 8 编译其余代码(通过使用javac 8
或使用新--release
标志 on javac 9
),您的库仍可在该版本上运行。
即使 Java 9 也只会将您的 JAR 作为模块处理,前提是它最终位于模块路径上。只有这样,它才会看到子句并在模块图requires
中包含您正在使用的 Java EE 模块。这意味着在 Java 9 的类路径上使用您的库的客户端仍然必须通过命令行手动添加这两个模块。
如果您的模块用于模块路径,可访问性规则确保:
这表示:
特别是如果您依赖尚未模块化的项目,第二点可能会很困难,但这是另一个问题。
可能是 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