【发布时间】:2015-05-11 12:36:19
【问题描述】:
我最近在我的应用程序中看到了我无法解释的奇怪行为。它们发生的频率很低,所以我无法重现它们。虽然这些问题发生的地方发生了变化,但共同的部分似乎是数组在创建后会改变大小(我知道,这是不可能的,因此:奇怪的行为)。
举几个例子来说明我的观点:
java.lang.StringIndexOutOfBoundsException: String index out of range: 86
at java.lang.String.checkBounds(String.java:409)
at java.lang.String.<init>(String.java:577)
at com.acunia.fleet.diagnostics.providers.tacho.VDOKLineInputParser.getRealDriverID(Unknown Source)
导致这种情况的代码:
public String getRealDriverID(byte[] buffer) {
if (buffer.length > 86 && isDriverCardInserted(buffer)) {
return new String(buffer, 70, 16);
}
return null;
}
所以我们首先检查缓冲区是否足够大(超过 86 个字节),然后再尝试从它们创建字符串。
第二个例子:
java.lang.ArrayIndexOutOfBoundsException: -1
at java.lang.String.lastIndexOf(String.java:1889)
at java.lang.String.lastIndexOf(String.java:1835)
at java.lang.String.lastIndexOf(String.java:1817)
at com.acunia.service.position.nmea.comm.CommPositionProvider.isValid(Unknown Source)
导致此异常的行是:
int csi = line.lastIndexOf("*");
我查看了 openjdk String.java 源代码,但找不到错误,除非数组在创建后突然开始改变大小。
我能找到的唯一可能相关的在线参考是一个 openjdk 错误:https://bugs.openjdk.java.net/browse/JDK-6817012。不过,这个错误被标记为“不是问题”,尽管在阅读本文时,我无法真正判断所提到的问题是否未被识别为错误,或者关闭错误的人是否不明白为什么会出现这个错误会引起问题。
如果有人遇到过类似的问题,我会非常感激听到它。就目前而言,这个问题太不稳定了,无法尝试使用其他版本的 openjdk 来修复它。
问题出现在:
hardware: custom arm platform
java version "1.6.0_31"
OpenJDK Runtime Environment (IcedTea6 1.13.3) (6b31-1.13.3-1~deb7u1)
OpenJDK Zero VM (build 23.25-b01, mixed mode)
Linux 3.2.0 #1 Fri Jun 20 10:25:16 CEST 2014 armv7l GNU/Linux
【问题讨论】:
-
您正在使用 Java 6。Java 7 刚刚达到生命的尽头。你真的应该升级你的 Java。
-
如果字符没有出现在字符串中,第二个例子很容易解释。在这种情况下,lastIndexOf 返回 -1,投诉是关于使用索引 -1。
-
如果可能的话,我还建议您将 Java 升级到 8。最好是 Oracle 版本。 OpenJDK 让我感到头疼。
-
该应用程序在遍布欧洲的嵌入式设备上运行(在移动的车辆中)。虽然更新这些是可能的,但代价高昂。此外,如果没有明确的迹象表明该问题在最近的 Java 版本中不再存在,我会感到不舒服。
-
lastIndexOf 如果字符没有出现应该返回 -1,但是它不应该抛出 ArrayIndexOutOfBoundsException