Rai*_*baz 5 java java-ee maven java-9 java-11
我目前正在将一个开源库移植到JDK9 +兼容,它依赖于Java 9中已弃用并在Java 11中删除的一些Java EE模块:特别是JAXB,JAX-WS和javax.annotation.
我添加显式依赖于第三方实施的建议在这里:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-ri</artifactId>
<version>2.3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
但是,我希望我的库只在必要时使用它们(即在JDK9 +上)并继续使用JDK8上的认可实现.
我可以通过在Maven配置文件中添加仅在JDK 9及更高版本上激活的依赖项来实现,但是如果我想在Maven Central上为我的库发布jar文件呢?我是否应该发布两个不同的jar,一个包含Java EE第三方实现,用于JDK9 +,另一个没有用于JDK8?
有没有办法生成一个jar文件,它将使用JDK9 +上的第三方实现和JDK8上的背书实现?
我已经研究过多版本jar,但看起来它们是用于项目类之间的jdk版本相关实现,而不是依赖项.
此外,如果无法在JDK 8上使用认可的实现,有没有办法可靠地测试使用第三方实现不会引入任何回归?
有没有办法生成一个 jar 文件,该文件将使用 JDK9+ 上的第三方实现和 JDK8 上认可的实现?
很不幸的是,不行。通过 jar 文件分发库时,您无法控制其他 jar 和库在类路径中的列出方式。这使得类加载对您来说具有不确定性。对于您的情况来说,这意味着如果上述库包含在 JDK8 环境中的类路径中,则无法确定或控制加载哪个版本的类。
另外,如果无法在 JDK 8 上使用认可的实现,是否有一种方法可以可靠地测试使用第三方实现不会引入任何回归?
作为作者,您需要在不同的运行时环境中执行测试以检查回归情况。
我是否应该发布两个不同的 jar,其中一个包含 Java EE 第三方实现(适用于 JDK9+),而另一个则不包含适用于 JDK8(适用于 JDK8)?
这是一个完全合理的解决方案,其他人以前也使用过。以sqlserver jdbc jar为例,它基于jre有不同的版本:https: //learn.microsoft.com/en-us/sql/connect/jdbc/using-the-jdbc-driver ?view=sql-server- 2017 对于此处描述的情况,jar 的 JDK9+ 版本可以声明您在问题中提到的附加依赖项,而 JDK8 版本则不会。
另一种选择是使用一个 jar 并声明您所提供的依赖项。这将向使用者发出信号,表明运行时环境必须包含声明的依赖项中的类。需要一些文档来指导库的使用者何时必须显式地将声明为提供的 jar 添加到其类路径中。
恕我直言,最清晰的解决方案是两个 jar,并在 jar 名称和不同的依赖项中引用 JRE 版本。它只需要很少的文档(无论如何大多数人都不会看)。它允许您更自由地对库进行更改。