我們遇到了迄今爲止無法解決的錯誤,但沒有明顯的原因或解決方案。變更的最終屬性
在對包含從文件加載的數據的數組進行多次訪問時發生該錯誤。 ArrayIndexOutOfBounds發生在與此數組一起使用的代碼的各個部分中。
變量似乎隨機更改值。爲了防止這種情況,我們嘗試將修飾符「final」放入所有類屬性中。但他們仍然隨機改變價值。
下面,方法「執行()」及其內部循環「,而」它是發生錯誤的應用程序點。
public Set<Long> execute(InputStream datIn, int qtd) throws PersistenceException {
if (this.criterion == null) {
throw new PersistenceException("Não foi especificado filtro para a busca");
}
this.criterion.configure(info);
try {
Set<Long> retorno = new HashSet<Long>(qtd);
byte[] b = new byte[Serializator.BUFFER_SIZE];
int bl = datIn.read(b, 0, Serializator.BUFFER_SIZE);
int br = bl, bp = 0, nbp = 0, blockSize, i, p = 0;
while (p++ < qtd) {
System.out.println("P = "+p);
bp = nbp;
int aux = ByteArrayUtils.toUnsignedShort(b, bp);
System.out.println("aux = "+aux);
blockSize = aux + indexBlockSize;
System.out.println("indexBlockSize = "+indexBlockSize);
System.out.println("blockSize = "+blockSize);
if (br < blockSize + 2) {
for (i = 0; i < br; i++) {
b[i] = b[i + bp];
}
bl = datIn.read(b, br, Serializator.BUFFER_SIZE - br) + br;
bp = 0;
br = bl;
}
nbp = bp + blockSize;
br -= blockSize;
System.out.println("b.length = "+b.length);
System.out.println("bp = "+bp);
System.out.println("headerSize = "+headerSize);
if (this.criterion.doCompare(b, bp, headerSize)) {
retorno.add(getSearchedValue(b, bp));
if (retorno.size() == this.maxResults) {
break;
}
}
}
return retorno;
} catch (IOException e) {
throw new PersistenceException(e);
}
}
下面的方法中出現的 「執行()」 的代碼:
getSearchValue:)
public long getSearchedValue(byte[] b, int bp) {
if (this.fieldReturn == -1) {
return ByteArrayUtils.toLong(b, bp + 2);
} else {
if (b[this.bitSetPosition + bp] >= 0) {
int off = ByteArrayUtils.toShort(b, bp + rIndex) + headerSize + bp;
return ByteArrayUtils.readOptimizedLong(b, off);
} else {
return 0;
}
}
}
ByteArraysUtils.toShort(:
public static short toShort(byte[] byteArray, int off) {
System.out.println("ByteArrayUtils: toShort: byteArray.length="+byteArray.length
+" off = "+off);
return (short) ((byteArray[off + 1] & 0xFF) | ((byteArray[off] & 0xFF) << 8));
}
ByteArraysUtils .toUnsignedShort():
public static int toUnsignedShort(byte[] byteArray, int off) {
System.out.println("ByteArrayUtils: toUnsignedShort: byteArray.length="+byteArray.length
+" off = "+off);
return ((int) 0) | ((byteArray[off + 1] & 0xFF) | ((byteArray[off] & 0xFF) << 8));
}
Criterion.doCompare():
public boolean doCompare(byte[] data, int offset, int headerSize) throws PersistenceException {
System.out.println("doCompare: data.length = "+data.length+" offset = "+offset
+" this.position = "+this.position);
if (data[offset + this.position] >= 0) {
short off = ByteArrayUtils.toShort(data, offset + this.position);
return this.def.verify(data, off + offset + headerSize);
} else {
return this.def.verifyNull();
}
}
下面是執行過程中生成的錯誤的一些日誌:
錯誤1:在COM java.lang.ArrayIndexOutOfBoundsException : 致.wealthsystems.util.api.array.ByteArrayUtils.toShort(ByteArrayUtils.java:123) at com.wealthsystems.persistence.impl.search.criterion.Criterion.doCompare(Criterion.java:64) at com.wealthsystems.persistence.impl.search.DatSearch.execute(DatSearch.java:133)
錯誤2: 6841 LoginActivity Falha日登錄java.lang.ArrayIndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException 在com.wealthsystems .persistence.impl.search.criterion.Criterion.doCompare(Criterion.java:61)
錯誤3: 1002575 LoginActivity Falha日登錄java.lang.ArrayIndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException 在com.wealthsystems。 util.api.array.ByteArrayUtils.toUnsignedShort(ByteArrayUtils.java:129)
正如我們所看到的,錯誤發生在許多不同的位置,但變量的值總是相同的,即錯誤似乎是隨機的。這是通過打印變量來驗證的(因爲當我們打開調試時錯誤不會發生),通過打印,我們看到變量的奇怪變化。下面是生成的打印的一些例子:
打印1:
P = 746
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 22400
aux = 100
indexBlockSize = 58
blockSize = 158
b.length = 32767
bp = 22400
headerSize = 65
doCompare: data.length = 32767 offset = 22400 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 22410
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 22465
P = 747
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 22558
aux = 99
indexBlockSize = 58
blockSize = 157
b.length = 32767
bp = 22558
headerSize = 65
doCompare: data.length = 32767 offset = 22558 this.position = 10
java.lang.ArrayIndexOutOfBoundsException
at com.wealthsystems.persistence.impl.search.criterion.Criterion.doCompare(Criterion.java:62)
at com.wealthsystems.persistence.impl.search.DatSearch.execute(DatSearch.java:121)
at com.wealthsystems.persistence.impl.retrieve.DatRetrieve.search(DatRetrieve.java:62)
注意,在「doCompare()」將被訪問的索引「[偏移+ this.position]」,但該錯誤在索引訪問22568中被指控。該索引小於向量的大小(「data.length」)。
打印2:
P = 578
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 28651
aux = 114
indexBlockSize = 58
blockSize = 172
b.length = 32767
bp = 28651
headerSize = 65
doCompare: data.length = 32767 offset = 28651 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 28661
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 28716
P = 579
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 28823
aux = 114
indexBlockSize = 58
blockSize = 22618
b.length = 32767
bp = 0
headerSize = 65
doCompare: data.length = 32767 offset = 0 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 10
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 65
P = 580
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 22618
aux = 65280
indexBlockSize = 58
blockSize = 87784
b.length = 32767
bp = 0
headerSize = 65
doCompare: data.length = 32767 offset = 0 this.position = 10
P = 581
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 87784
28493 LoginActivity Falha de login java.lang.ArrayIndexOutOfBoundsException
java.lang.ArrayIndexOutOfBoundsException
at com.wealthsystems.util.api.array.ByteArrayUtils.toUnsignedShort(ByteArrayUtils.java:131)
at com.wealthsystems.persistence.impl.search.DatSearch.execute(DatSearch.java:98)
at com.wealthsystems.persistence.impl.retrieve.DatRetrieve.search(DatRetrieve.java:62)
注執行P = 579. 的輔助值是114 indexBlockSize的值是58。BLOCKSIZE值應172.但看來BLOCKSIZE的值= 22618.
打印3:
P = 1
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 0
aux = 144
indexBlockSize = 58
blockSize = 202
b.length = 32767
bp = 0
headerSize = 65
doCompare: data.length = 32767 offset = 0 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 10
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 65
P = 2
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 202
aux = 96
indexBlockSize = 58
blockSize = 154
b.length = 32767
bp = 202
headerSize = 65
doCompare: data.length = 32767 offset = 202 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 212
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 267
P = 3
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 356
aux = 115
indexBlockSize = -7696
blockSize = -7581
b.length = 32767
bp = 356
headerSize = 65
doCompare: data.length = 32767 offset = 356 this.position = 10
ByteArrayUtils: toShort: byteArray.length=32767 off = 366
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = 421
P = 4
ByteArrayUtils: toUnsignedShort: byteArray.length=32767 off = -7225 61680
LoginActivity Falha de login java.lang.ArrayIndexOutOfBoundsException java.lang.ArrayIndexOutOfBoundsException
at com.wealthsystems.util.api.array.ByteArrayUtils.toUnsignedShort(ByteArrayUtils.java:131)
at com.wealthsystems.persistence.impl.search.DatSearch.execute(DatSearch.java:98)
at com.wealthsystems.persistence.impl.retrieve.DatRetrieve.search(DatRetrieve.java:62)
這是最關鍵的錯誤,因爲變量「indexBlockSize」是私有的,並在構造函數初始化uctor並且不再被修改,但是在運行過程中,它會更改indexBlockSize = -7696(執行P = 3)的值。
設備中發生錯誤:
- IBAK-775(固件:2.1 update1-1.0.0)(內核:2.6.25)(頻率:誤差非常常見); LG Optimus One P500(Android版本:2.2.2)(內核:2.6.32.9)(頻率:錯誤不常見);三星Galaxy Tab GT-P1000(Android:2.2)(頻率:常見錯誤);
- 三星I5800 Galaxy 3(Android 2.2)(頻率:常見錯誤)。
設備中的錯誤從來沒有發生過:
- 以上所有的設備,在Eclipse中的調試模式下運行;
- 任何Android版本的仿真器;摩托羅拉Spice XT300(固件:2.1-update1)(內核:2.6.29); - 三星Galaxy 5(GT-I5500B)(固件:2.1-update1)(內核:2.6.29);
- Motorola Xoom(Android 3.0);
- Samsung Galaxy Tab 8.9(Android 3.0)。
不幸的是,我們無法將外部代碼中的錯誤隔離到我們的應用程序,您能夠重現錯誤。所有試圖將代碼從我們的應用程序中分離出來的嘗試都沒有產生錯誤。但希望你能給我們提供一些關於我們正在發生的事情的信息!
我們在互聯網上對這個錯誤的研究只顯示了這個頁面:http://www.androiddiscuss.com/1-android-discuss/96129.html。看起來像有人遇到類似的問題,但在討論中沒有解決方案。
屬性的聲明和類的構造函數:
private byte fieldReturn;
private EntityInfo info;
private final short rIndex, indexBlockSize;
private ICriterion criterion = null;
private int headerSize;
private int maxResults;
private int bitSetPosition;
public DatSearch(byte fieldReturn, EntityInfo info) {
this.fieldReturn = fieldReturn;
this.bitSetPosition = (this.fieldReturn == -1) ? -1 : 10 + (fieldReturn * 2);
this.info = info;
this.rIndex = (fieldReturn >= 0) ? (short) (10 + (fieldReturn << 1)) : 0;
short qtdIndices = (short) info.getMapper().getIndexes().length;
this.indexBlockSize = (short) (10 + (qtdIndices << 1));
this.headerSize = indexBlockSize + info.getBitSetLength();
}
我試圖把這一類的所有變量外的其他類,並獲取並設置讀出來,但是這個解決辦法沒有奏效。
1.有多少線程在做這個? 2.你究竟如何定義indexBlockSize變量?而final關鍵字只意味着你不能在其範圍內更改該變量的值,並且該變量超出範圍並且是可修改的。我還有一個想法,請顯示indexBlockSize變量的所有用法以及它的定義。謝謝。 – 2012-01-30 20:45:20
你也可以閱讀關於java和垃圾收集中的可變和不可變對象/類型 – 2012-01-30 21:12:26
1.只有一個線程。 2.我添加了屬性聲明和類構造函數。 indexBlockSize變量僅在此方法中使用且從不寫入。 – user1178849 2012-01-31 11:43:46