选择性地将第三方实现用于不推荐使用的JavaEE模块

时间:2019-01-02 16:01:44

标签: java maven java-ee java-9 java-11

我当前正在移植一个兼容JDK9 +的开源库,它取决于Java 9中已弃用并在Java 11中删除的某些Java EE模块:特别是JAXB,JAX-WS和javax.annotation

我按照建议的here向第三方实现添加了显式依赖项:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2309, in __call__
return self.wsgi_app(environ, start_response)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2295, in wsgi_app
response = self.handle_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1741, in handle_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 2292, in wsgi_app
response = self.full_dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1815, in full_dispatch_request
rv = self.handle_user_exception(e)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1718, in handle_user_exception
reraise(exc_type, exc_value, tb)
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1813, in full_dispatch_request
rv = self.dispatch_request()
  File "/Library/Python/2.7/site-packages/flask/app.py", line 1799, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
  File "/Users/larssuanet/Documents/enjins/dscs/flask_api.py", line 39, in store_model
model = pickle.loads(request.get_data())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1382, in loads
return Unpickler(file).load()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 886, in load_proto
raise ValueError, "unsupported pickle protocol: %d" % proto
ValueError: unsupported pickle protocol: 3

但是,我希望我的库仅在必要时(例如,在JDK9 +上)使用它们,并继续在JDK8上使用认可的实现。

我可以通过在Maven配置文件中添加依赖项(仅在JDK 9及更高版本上才能激活)来实现,但是如果我想在Maven Central上为我的库发布jar文件怎么办?我是否应该针对JDK9 +发布两个不同的jar,其中一个包含Java EE第三方实现,而对于JDK8,则不包括其中?

有没有一种方法可以生成将使用JDK9 +上的第三方实现以及JDK8上认可的jar实现的jar文件?

我已经研究过multi-release jars,但看起来它们是供项目类中而不是依赖项中与jdk版本相关的实现使用的。

此外,如果无法在JDK 8上使用认可的实现,是否有办法可靠地测试使用第三方实现不会引入任何回归?

1 个答案:

答案 0 :(得分:1)

  

有没有一种方法可以生成将使用第三方的jar文件   在JDK9 +上实现并在JDK8上实现?

不幸的是,没有。通过jar文件分发库时,您无法控制如何在类路径中列出其他jar和库。这使类加载对于您而言不确定。对于您的情况意味着,如果在JDK8环境中的类路径中包含上述库,则无法确定或控制要加载哪个版本的类。

  

此外,如果无法在上使用认可的实现   JDK 8,有没有一种方法可以使用第三方可靠地测试   实现没有引入任何回归?

作为作者,您将需要在不同的运行时环境中执行测试以检查回归。

  

我应该发布两个不同的jar,其中一个与Java EE第三方一起发布   包括针对JDK9 +的实现和不针对JDK8的实现?

这是其他人也曾经使用过的完全合理的解决方案。以sqlserver jdbc jar为例,这些jar基于jre具有不同的版本:https://docs.microsoft.com/en-us/sql/connect/jdbc/using-the-jdbc-driver?view=sql-server-2017 对于此处描述的情况,jar的JDK9 +版本可以声明您在问题中提到的其他依赖项,而JDK8版本则不能。

另一个选择是拥有一个jar并声明所提供的依赖项。这将向使用者表明运行时环境必须在声明的依赖项中包括这些类。将需要一些文档来指导库的使用者有关何时必须将明确声明为所提供的jar添加到其类路径的提示。

恕我直言,最清晰的解决方案是两个jar,在jar名称中引用JRE版本,并具有不同的依赖关系。它需要的文档很少(无论如何,大多数都不会看)。它使您可以更自由地在库中进行更改。