Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4422319

Intermittent ArrayIndexOutofBoundsException thrown, works OK with -server

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.4.0
    • hotspot
    • None
    • beta
    • x86
    • windows_nt

      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


            busersunw Btplusnull User (Inactive)
            spandeorcl Shantaram Pande (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: