スタック トレースはかなり長いですが、関連するセクションを次に示します。
Caused by: java.lang.ArrayIndexOutOfBoundsException: 33
at java.lang.String.equals(String.java:1018)
at java.util.HashMap.get(HashMap.java:305)
そのため、 から要素を取得するとHashMap<String,?>
、String#equaqls が呼び出されます。次に、行からスローされた ArrayIndexOutOfBoundExceptionif (v1[i++] != v2[j++])
// Sun java 1.6
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
本当に変です。
アップデート。例外は、ログ分析プログラムから取得されます。そこではリフレクションを使用しませんでした。また、文字列オブジェクトが破損している何かについても考えましたが、コードからは何の手がかりも得られませんでした。そして、この問題は再起動後に再現しませんでした。リトライし続けると再現するかどうかわかりません。
LogUtils
public static Map<String, String> parseLine(String line) { if (StringUtils.isEmpty(line)) { return Collections.emptyMap(); } String[] parts = StringUtils.split(line, '\t'); Map<String, String> results = new HashMap<String, String>(); for (String part : parts) { String[] keyVal = StringUtils.split(part, "=", 2); if (keyVal.length == 2) { String key = keyVal[0]; String value = keyVal[1]; results.put(key, value); } } return results; } public static void process(String fileName, Date date, Closure closure) throws IOException { InputStream is = null; Reader r = null; try { is = new FileInputStream(getFilename(fileName, date)); is = new BufferedInputStream(is); is = new GZIPInputStream(is); r = new InputStreamReader(is, "utf8"); LineIterator iter = IOUtils.lineIterator(r); while (iter.hasNext()) { String line = iter.nextLine(); Map<String, String> map = LogUtils.parseLine(line); closure.execute(map); } } finally { IOUtils.closeQuietly(r); IOUtils.closeQuietly(is); } }
閉鎖
public void execute(Map<String, String> line) { if (dataMap == null) { dataMap = new HashMap<String, Map<Long, Integer>>(); } String identifier = line.get(Constants.IDENTIFIER_KEY); // Exception thrown from there /* ...blahblah... */ }
簡単にするために、クロージャー オブジェクトを作成し、LogUtils.process
それを呼び出します。LogUtils は改行 (例: key1=value1\tkey2=value2\t...kn=valuen
) のように にしHashMap
ます。次にLogUtils
、マップをクロージャーに渡します。line.get(Constants.IDENTIFIER_KEY);
また、 Constants.IDENTIFIER_KEY が static final フィールドの場合から例外がスローされます。したがって、equals メソッドの lhs および rhs は静的な最終文字列であり、戻り値はStringUtils.split(line, '\t')
です。commons-lang のコードを確認しました。実物String#substring
です。それで、それはまだ奇妙です。