It is apparently a VM bug. It dissapears if one uses -server flag.
Shantaram found that it appears on Windows 98/2000/NT and Linux,
it has not been reproduced on Solaris.
On my machine it happens intermittently - sometimes it happens at once.
sometimes I need to run the test couple of times before getting the
exception.
Shantaram's test program contains two tests, the bug appears in Test02.
I have tried removing Test01, then the bug dissapears. In general small
changes in code change bug's behaviour. Thats why we are unable to
produce a shorter example.
Apparently Test01 puts a load on a VM in some sense, so Test02
fails.
PutByteArray calls java.util.prefs.Base64.byteArrayToBase64 function which
encodes a byte array into a character string using Base64 encoding.
It is a pretty straightforward function, which does not use any native
code etc. The ArrayIndexOutOfBounds exception is thrown intermittently
from this function.
It would be nice to reproduce the bug by a simpler program which would
just call byteArrayToBase64 on Shantaram's array, but then the
problem dissapears, at least on my machine. In general this
thing is machine dependent - Shantaram gets it all the time,
and for me its much harder to reproduce it, probably because
I have a newer machine with more memory etc.
Shantaram's array is pretty large - its size is java.util.prefs.Preferences.MAX_VALUE_LENGTH*3/4 +1,
could this be the cause of the problem?
Linux and Windows have absolutely different native implementations
of java.util.prefs, so the problem is not with the native code, which
is used in some calls of Test01, which precedes Test02
If you have question or problems with the test program I will be happy
to help
konstantin.kladko@Eng 2001-03-12
jdk1.4 build53 test program passes on winnt.
jdk1.4 build54 test program fails on winnt.
Test program and result is given below.
----------------Test program---------------------------------
import java.util.prefs.*;
import java.util.*;
public class PutByteArray {
static final int TOTAL = 10000;
static final int ARRAYSIZE = 100;
public static void main(String[] args) throws Exception {
boolean status[];
int passcount = 0, failcount = 0;
int numTests = 2;
int i, j = 0;
status = new boolean[numTests];
System.out.println("Total tests for Exec : "+numTests);
for(i = 0; i < numTests; ++i) {
// PutByteArray all tests in try... catch block
try {
++j;
switch (j) {
case 1:
status[i] = PutByteArrayTest01();
break;
case 2:
status[i] = PutByteArrayTest02();
break;
}
} catch (Exception e) {
status[i] = false;
System.out.println ("Exception in test "+j+": "+e.getMessage());
e.printStackTrace();
}
} // end for
// Get pass and fail totals
for(i = 0; i < numTests; ++i) {
if (status[i] == true)
passcount++;
else
failcount++;
}
System.out.println("Pass count: " + passcount);
System.out.println("Fail count: " + failcount);
// check if tests passed
if ( failcount < 1 ) {
System.out.println("Test for PutByteArray.java Passed");
System.exit(0);
} else {
System.out.println("Test for PutByteArray.java Failed");
System.exit(1);
}
} // end main
/**
*
*PutByteArrayTest01: java.util.prefs.Preferences void putByteArray(java.lang.String key, byte[] value)
*Create userRoot preferences
*Create "N1" node in userRoot
*In "N1" put key "k1" and value byte[] value
*verify byte[] value is put by calling getByteArray() method, if ok then pass.
*
*/
public static boolean PutByteArrayTest01() {
boolean bReturn = false;
try {
Preferences userRoot = Preferences.userRoot();
Preferences N1 = userRoot.node("N1");
//N1.clear();
byte [] value = new byte[(Preferences.MAX_VALUE_LENGTH*3/4)];
for (int i =0; i < (Preferences.MAX_VALUE_LENGTH*3/4); i++) {
value[i]=(byte)i;
}
N1.putByteArray("k1",value);
byte[] valueExpected = value;
byte[] valuedefault = new byte[1];
valuedefault[0] = (byte)1;
byte[] valueGot = N1.getByteArray("k1",valuedefault);
for (int i=0; i<(Preferences.MAX_VALUE_LENGTH*3/4); i++) {
//System.out.println("value = " + value[i]);
//System.out.println("valueGot = " + valueGot[i]);
if (valueGot[i] != (valueExpected[i])) {
throw new Exception("valueGot[i] != (valueExpected[i] not ok in PutByteArrayTest01()");
}
}
bReturn = true;
System.out.println("PutByteArrayTest01() Pass");
} catch(Exception e) {
bReturn = false;
System.out.println("Exception thrown = " + e);
System.out.println("PutByteArrayTest01() Fail");
e.printStackTrace();
}
return bReturn;
}
/**
*
*PutByteArrayTest02: java.util.prefs.Preferences void putByteArray(java.lang.String key, byte[] value)
*Create userRoot preferences
*Create "N1" node in userRoot
*In "N1" put key "k1" and value byte[] value
*length of byte array is greater than MAX_VALUE_LENGTH*3/4 then if IllegalArgumentException is thrown then pass.
*
*/
public static boolean PutByteArrayTest02() {
boolean bReturn = false;
try {
Preferences userRoot = Preferences.userRoot();
Preferences N1 = userRoot.node("N1");
//N1.clear();
byte [] value = new byte[(Preferences.MAX_VALUE_LENGTH*3/4) +1];
for (int i =0; i < (Preferences.MAX_VALUE_LENGTH*3/4 +1); i++) {
value[i]=(byte)i;
}
N1.putByteArray("k1",value);
bReturn = false;
System.out.println("PutByteArrayTest02() Fail");
} catch(IllegalArgumentException iae) {
bReturn = true;
System.out.println("Expected IllegalArgumentException thrown PutByteArrayTest02()Pass");
} catch(Exception e) {
bReturn = false;
System.out.println("Exception thrown = " + e);
System.out.println("PutByteArrayTest02() Fail");
e.printStackTrace();
}
return bReturn;
}
}
-----------------------result on winNT jdk1.4 b54 fail----------------
H:\merlin\bugs\util\PutByteArray\t1>java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b54)
Java HotSpot(TM) Client VM (build B54, mixed mode)
H:\merlin\bugs\util\PutByteArray\t1>java PutByteArray
Total tests for Exec : 2
PutByteArrayTest01() Pass
Exception thrown = java.lang.ArrayIndexOutOfBoundsException
PutByteArrayTest02() Fail
java.lang.ArrayIndexOutOfBoundsException
at java.util.prefs.Base64.byteArrayToBase64(../../../src/share/classes/java/util/prefs/Base64.java:69)
at java.util.prefs.Base64.byteArrayToBase64(../../../src/share/classes/java/util/prefs/Base64.java:27)
at java.util.prefs.AbstractPreferences.putByteArray(../../../src/share/classes/java/util/prefs/AbstractPreferences.java:604)
at PutByteArray.PutByteArrayTest02(PutByteArray.java:129)
at PutByteArray.main(PutByteArray.java:29)
Pass count: 1
Fail count: 1
Test for PutByteArray.java Failed
----------------------------------------result on jdk1.4 b53 pass winnt---------
H:\merlin\bugs\util\PutByteArray\t1>j:\jdk1.4.bak\win\bin\java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b53)
Java HotSpot(TM) Client VM (build B53, mixed mode)
H:\merlin\bugs\util\PutByteArray\t1>j:\jdk1.4.bak\win\bin\java PutByteArray
Total tests for Exec : 2
PutByteArrayTest01() Pass
Expected IllegalArgumentException thrown PutByteArrayTest02()Pass
Pass count: 2
Fail count: 0
Test for PutByteArray.java Passed
Shantaram found that it appears on Windows 98/2000/NT and Linux,
it has not been reproduced on Solaris.
On my machine it happens intermittently - sometimes it happens at once.
sometimes I need to run the test couple of times before getting the
exception.
Shantaram's test program contains two tests, the bug appears in Test02.
I have tried removing Test01, then the bug dissapears. In general small
changes in code change bug's behaviour. Thats why we are unable to
produce a shorter example.
Apparently Test01 puts a load on a VM in some sense, so Test02
fails.
PutByteArray calls java.util.prefs.Base64.byteArrayToBase64 function which
encodes a byte array into a character string using Base64 encoding.
It is a pretty straightforward function, which does not use any native
code etc. The ArrayIndexOutOfBounds exception is thrown intermittently
from this function.
It would be nice to reproduce the bug by a simpler program which would
just call byteArrayToBase64 on Shantaram's array, but then the
problem dissapears, at least on my machine. In general this
thing is machine dependent - Shantaram gets it all the time,
and for me its much harder to reproduce it, probably because
I have a newer machine with more memory etc.
Shantaram's array is pretty large - its size is java.util.prefs.Preferences.MAX_VALUE_LENGTH*3/4 +1,
could this be the cause of the problem?
Linux and Windows have absolutely different native implementations
of java.util.prefs, so the problem is not with the native code, which
is used in some calls of Test01, which precedes Test02
If you have question or problems with the test program I will be happy
to help
konstantin.kladko@Eng 2001-03-12
jdk1.4 build53 test program passes on winnt.
jdk1.4 build54 test program fails on winnt.
Test program and result is given below.
----------------Test program---------------------------------
import java.util.prefs.*;
import java.util.*;
public class PutByteArray {
static final int TOTAL = 10000;
static final int ARRAYSIZE = 100;
public static void main(String[] args) throws Exception {
boolean status[];
int passcount = 0, failcount = 0;
int numTests = 2;
int i, j = 0;
status = new boolean[numTests];
System.out.println("Total tests for Exec : "+numTests);
for(i = 0; i < numTests; ++i) {
// PutByteArray all tests in try... catch block
try {
++j;
switch (j) {
case 1:
status[i] = PutByteArrayTest01();
break;
case 2:
status[i] = PutByteArrayTest02();
break;
}
} catch (Exception e) {
status[i] = false;
System.out.println ("Exception in test "+j+": "+e.getMessage());
e.printStackTrace();
}
} // end for
// Get pass and fail totals
for(i = 0; i < numTests; ++i) {
if (status[i] == true)
passcount++;
else
failcount++;
}
System.out.println("Pass count: " + passcount);
System.out.println("Fail count: " + failcount);
// check if tests passed
if ( failcount < 1 ) {
System.out.println("Test for PutByteArray.java Passed");
System.exit(0);
} else {
System.out.println("Test for PutByteArray.java Failed");
System.exit(1);
}
} // end main
/**
*
*PutByteArrayTest01: java.util.prefs.Preferences void putByteArray(java.lang.String key, byte[] value)
*Create userRoot preferences
*Create "N1" node in userRoot
*In "N1" put key "k1" and value byte[] value
*verify byte[] value is put by calling getByteArray() method, if ok then pass.
*
*/
public static boolean PutByteArrayTest01() {
boolean bReturn = false;
try {
Preferences userRoot = Preferences.userRoot();
Preferences N1 = userRoot.node("N1");
//N1.clear();
byte [] value = new byte[(Preferences.MAX_VALUE_LENGTH*3/4)];
for (int i =0; i < (Preferences.MAX_VALUE_LENGTH*3/4); i++) {
value[i]=(byte)i;
}
N1.putByteArray("k1",value);
byte[] valueExpected = value;
byte[] valuedefault = new byte[1];
valuedefault[0] = (byte)1;
byte[] valueGot = N1.getByteArray("k1",valuedefault);
for (int i=0; i<(Preferences.MAX_VALUE_LENGTH*3/4); i++) {
//System.out.println("value = " + value[i]);
//System.out.println("valueGot = " + valueGot[i]);
if (valueGot[i] != (valueExpected[i])) {
throw new Exception("valueGot[i] != (valueExpected[i] not ok in PutByteArrayTest01()");
}
}
bReturn = true;
System.out.println("PutByteArrayTest01() Pass");
} catch(Exception e) {
bReturn = false;
System.out.println("Exception thrown = " + e);
System.out.println("PutByteArrayTest01() Fail");
e.printStackTrace();
}
return bReturn;
}
/**
*
*PutByteArrayTest02: java.util.prefs.Preferences void putByteArray(java.lang.String key, byte[] value)
*Create userRoot preferences
*Create "N1" node in userRoot
*In "N1" put key "k1" and value byte[] value
*length of byte array is greater than MAX_VALUE_LENGTH*3/4 then if IllegalArgumentException is thrown then pass.
*
*/
public static boolean PutByteArrayTest02() {
boolean bReturn = false;
try {
Preferences userRoot = Preferences.userRoot();
Preferences N1 = userRoot.node("N1");
//N1.clear();
byte [] value = new byte[(Preferences.MAX_VALUE_LENGTH*3/4) +1];
for (int i =0; i < (Preferences.MAX_VALUE_LENGTH*3/4 +1); i++) {
value[i]=(byte)i;
}
N1.putByteArray("k1",value);
bReturn = false;
System.out.println("PutByteArrayTest02() Fail");
} catch(IllegalArgumentException iae) {
bReturn = true;
System.out.println("Expected IllegalArgumentException thrown PutByteArrayTest02()Pass");
} catch(Exception e) {
bReturn = false;
System.out.println("Exception thrown = " + e);
System.out.println("PutByteArrayTest02() Fail");
e.printStackTrace();
}
return bReturn;
}
}
-----------------------result on winNT jdk1.4 b54 fail----------------
H:\merlin\bugs\util\PutByteArray\t1>java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b54)
Java HotSpot(TM) Client VM (build B54, mixed mode)
H:\merlin\bugs\util\PutByteArray\t1>java PutByteArray
Total tests for Exec : 2
PutByteArrayTest01() Pass
Exception thrown = java.lang.ArrayIndexOutOfBoundsException
PutByteArrayTest02() Fail
java.lang.ArrayIndexOutOfBoundsException
at java.util.prefs.Base64.byteArrayToBase64(../../../src/share/classes/java/util/prefs/Base64.java:69)
at java.util.prefs.Base64.byteArrayToBase64(../../../src/share/classes/java/util/prefs/Base64.java:27)
at java.util.prefs.AbstractPreferences.putByteArray(../../../src/share/classes/java/util/prefs/AbstractPreferences.java:604)
at PutByteArray.PutByteArrayTest02(PutByteArray.java:129)
at PutByteArray.main(PutByteArray.java:29)
Pass count: 1
Fail count: 1
Test for PutByteArray.java Failed
----------------------------------------result on jdk1.4 b53 pass winnt---------
H:\merlin\bugs\util\PutByteArray\t1>j:\jdk1.4.bak\win\bin\java -version
java version "1.4.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta-b53)
Java HotSpot(TM) Client VM (build B53, mixed mode)
H:\merlin\bugs\util\PutByteArray\t1>j:\jdk1.4.bak\win\bin\java PutByteArray
Total tests for Exec : 2
PutByteArrayTest01() Pass
Expected IllegalArgumentException thrown PutByteArrayTest02()Pass
Pass count: 2
Fail count: 0
Test for PutByteArray.java Passed
- relates to
-
JDK-4425555 [c1.merlin.b56] Unexpected array out of bounds exception on sparc moleculeviewer
-
- Resolved
-