Java 9失败以及如何修复它们

首先,我们说这是一个没有判断力的区域。 正如CodeFX的作者和热情的软件开发人员Nicolai Parlog在http://java9.wtf/页面的描述中说的那样,其目的不是玩怪罪游戏,而是展示Java 9上可能发生的事情。

未来的麻烦:Java 9打h

新的编译错误

Nicolai指出对javac的更改可能会导致新的编译错误 。 他解释说,编译错误的根源可能是Java 9编译器的类型推断在某些情况下工作不同的事实。 他写道:“该项目中的所有文件都可以使用Java 8很好地编译,但是不能使用Java 9进行编译。” Nicolai敦促读者寻找注释// fail看到什么不起作用,并// pass使其能够在Java 9中工作的修复程序。

一些错误可能来自(int) Comparable<T>类的强制转换

public void spinnerModel(SpinnerNumberModel spinnerModel) {
	// this could have happened somewhere else:
	// spinnerModel.setMinimum(0);
	// spinnerModel.setMaximum(360);
	// spinnerModel.setValue(45);

	int newValue = (int) spinnerModel.getValue() + 1;
	newValue = Math.min(newValue, (int) spinnerModel.getMaximum()); // fail
	newValue = Math.max(newValue, (int) (Object) spinnerModel.getMinimum()); // pass
	spinnerModel.setValue(newValue);
}

一些具有通用数组的恶作剧会停止工作:

public static <I> Optional[] lift(I[] array) { ... }
public static <T> T[] flatten(Optional<T>[] array) { ... }

private Stream<T[]> streamSelectionPaths() {
	Object[][] things2d = new Object[0][0];
	return Arrays
			.stream(things2d)
//			.map(thing -> (Optional<T>[]) lift(thing)) // pass
			.map(GenericArray::lift) // fail
			.map(GenericArray::flatten);
}
(最后检查:8u131和9-ea + 172-jigsaw)

下一站:Maven JAXB2插件

Nicolai写道, Maven JAXB2插件无法在Java 9上处理架构绑定 ,并解释说,可以通过运行插件并随后测试期望的类的存在来证明该问题。 但是,这并不是最烦人的部分:如果没有插件,就无法重新创建错误。

wtf.java9.maven_jaxb2_plugin中的代码是该插件正在运行的代码的简化版本(无意中“正确化”了吗?),但正如另一项测试所示,它可在Java 8和Java 9上运行。

使用mvn clean test运行项目会创建两个generated-jaxb-*文件夹,一个用于插件创建的源,另一个用于JAXB API。 尽管它们在Java 8上是相同的,但对于Java 9却不能说相同。正如Nicolai解释的那样, 测试试图验证源是否存在并因此在Java 9上失败。

(最后检查:8u131和9-ea + 172-jigsaw)

该项目的发布版本使用JAXB2插件的版本0.13.2。 使它与Java 9特定版本一起使用的努力也未成功。 这些努力可以在Maven JAXB2插件的这个私有分支中进行跟踪。

为了缓慢地处理插件的实现,实现了不同的变体,尤其是关于使用的EntityResolver 。 您可以在EntityResovlerFactory看到它们,然后选择它们作为Maven属性entity.resolver. 例如:

mvn clean test -Dentity.resolver=simple

默认情况下,插件的方法会尽可能接近地复制。

还请参见: 阐明了Java 9功能:JDK 9 Early Access文档已发布

第三招:Noto Sans字体

您应该知道,在Java 9上使用Noto Sans字体与在Java 8上使用Noto Sans字体是不同的-在速度方面(至少在Linux上)。 根据Nicolai的说法,问题似乎出在T2KFontScaler的创建上,它深深地出现在计算组件首选大小的过程中:

Font2D font = FontUtilities.getFont2D(new Font("Noto Sans CJK JP Black", 0, 12));
Constructor<?> constructor = Class
		.forName("sun.font.T2KFontScaler")
		.getConstructor(Font2D.class, int.class, boolean.class, int.class);
constructor.setAccessible(true);
// for this to not end in a heap dump you need to have Noto Sans CJK JP Black
// installed on your machine
Object scaler = constructor.newInstance(font, 0, true, 18604592);

更糟糕的是:如果这种情况发生在紧密的循环中(例如,显示标签列表的大小,每个标签使用不同的字体),剩下要做的就是排除这些字体。

如果测试运行时间超过半秒,则该测试试图通过使测试失败来证明性能差异。 但是,由机器来“决定”这是否足以在Java 8上成功而在Java 9上失败。

(最后检查:8u131和9-ea + 172-jigsaw)

XML转换器疯狂

javax.xml.transform.Transformer的行为已发生很大变化。

让我们举个例子:

// prepare an XML file as a DOM Source
String xml = "...";
Document document = DocumentBuilderFactory
		.newInstance()
		.newDocumentBuilder()
		.parse(new InputSource(new StringReader(xml)));
// maybe add some nodes or CDATA content

// transform the XML
Source source = new DOMSource(document);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
// maybe configure transformer
StringWriter outputWriter = new StringWriter();
transformer.transform(source, new StreamResult(outputWriter));
String transformedXml = outputWriter.toString();

// now compare `xml` and `transformedXml`

在Java 8和9之间(带有和不带有配置以及带有和不带有xml:space="preserve"不同。 这是最常见的行为:

  • 现有的压痕仍然存在
  • 包括CDATA在内的新节点是内联的

如果未将转换器配置为超出默认值并且与xml:space="preserve"无关,则可以注意到这一点。 但是,当使用OutputKeys.INDENT=yesindent-amount=4配置转换器时,Java 8和9的行为会有所不同。 在Java 8上,您将获得以下内容:

  • 现有的压痕仍然存在
  • 根据设置缩进新节点
  • CDATA不缩进

就Java 9而言,将发生以下情况:

  • 整个文档根据设置缩进,包括一堆乱码
  • 因此,新节点缩进
  • CDATA也加入了新的行,并且缩进了,从根本上改变了XML!

Nicolai补充说,通过进一步配置,很明显xml:space="preserve"行为也有所不同。 尽管它对Java 8毫无影响,但在Java 9上也没有作用(这使我们回到了首先描述的“无变化”的情况)。

该测试使用JUnit 5的嵌套测试来证明该行为。

(最后检查:8u131和9-ea + 172-jigsaw)

有助于

非常欢迎您提供文稿,如果您有任何问题,请打开一个问题 。 但是,如果您想做出贡献,请确保您的演示中尽可能多地选中以下框:

  • 它应该尽可能小
  • 它应该是Maven模块,其中mvn clean test在Java 8上通过但在Java 9上失败
  • 它无需进行大量编辑即可演示行为:
    • 如果编译器或Surefire在不同版本上需要不同的参数,请使用配置文件
    • 如果整个Maven运行都需要参数,请查看.mvn/jvm.config工作方式
  • 它的自述文件应该描述问题,可能显示一些代码(并链接到更多代码),并指出解决方案(如果有); 另外,别忘了从上方链接到它
  • 自述文件还应提及观察到所描述行为的Java 8和9版本

检出页面和/或Github存储库

翻译自: https://jaxenter.com/java-9-fails-code-breaks-135036.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值