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

when you convert a byte[] to a String and back with negative numbers it fails

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 5.0
    • core-libs
    • sparc
    • solaris_8, solaris_9

      FULL PRODUCT VERSION :
      bash-2.03$ java -version
      java version "1.4.2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
      Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)
      and
      java version "1.5.0_01"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_01-b08)
      Java HotSpot(TM) Client VM (build 1.5.0_01-b08, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      SunOS tb6db 5.8 Generic_108528-24 sun4u sparc SUNW,UltraSPARC-IIi-cEngine
      SunOS jeffblade 5.9 Generic_112233-08 sun4u sparc SUNW,Sun-Blade-100

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      This bug only occurs under Solaris 8, it works properly under Solaris 9. I have included system information about both systems tested. The Solaris 8 box has the latest J2SE patch cluster and the Latest recommended OS patch cluster as of yesterday (11-5-2003).

      A DESCRIPTION OF THE PROBLEM :
      When I convert a byte[] to a String and the byte array contains a negative value, it isn't handled correctly under Solaris.
      Here is a test program to illustrate the problem:

      public class Test {
          public Test() {
              byte[] aby = new byte[] { 0x31, (byte)0xBC };
              String str = new String(aby);
              byte[] by2 = str.getBytes();
          }

          public static void main(String[] args) {
              Test test1 = new Test();
          }
      }

      Basically you need to run this through the debugger to see the problem. by2[1] winds up with the value of 63 instead of -68 like it should get. Here is a debug output with jdb under Solaris 8:
      > stop at Test:12
      Deferring breakpoint Test:12.
      It will be set after the class is loaded.
      > run Test
      run Test
      Set uncaught java.lang.Throwable
      Set deferred uncaught java.lang.Throwable
      >
      VM Started: Set deferred breakpoint Test:12

      Breakpoint hit: "thread=main", Test.<init>(), line=12 bci=4

      main[1] step

      Step completed: "thread=main", Test.<init>(), line=13 bci=18
      main[1]
      main[1] locals
      Method arguments:
      Local variables:
      aby = instance of byte[2] (id=277)
      main[1] print aby[0]
       aby[0] = 49
      main[1] print aby[1]
       aby[1] = -68
      main[1] step
      >
      Step completed: "thread=main", Test.<init>(), line=14 bci=27

      main[1] locals
      Method arguments:
      Local variables:
      aby = instance of byte[2] (id=277)
      str = "1"
      main[1] step
      >
      Step completed: "thread=main", Test.<init>(), line=15 bci=32

      main[1] locals
      Method arguments:
      Local variables:
      aby = instance of byte[2] (id=277)
      str = "1?"
      by2 = instance of byte[2] (id=281)
      main[1] print by2[0]
       by2[0] = 49
      main[1] print by2[1]
       by2[1] = 63
      main[1] exit

      Notice how the value changed. Basically all negative values end up with the value of 63. I have done the test with multiple negative bytes in the array that all had different values and they all end up with 63 in their value.

      Here is an output of what you should get and what we get with our machines running Solaris 9:

      > stop at Test:12
      Deferring breakpoint Test:12.
      It will be set after the class is loaded.
      > run Test
      run Test
      Set uncaught java.lang.Throwable
      Set deferred uncaught java.lang.Throwable
      >
      VM Started: Set deferred breakpoint Test:12

      Breakpoint hit: "thread=main", Test.<init>(), line=12 bci=4

      main[1] step

      Step completed: "thread=main", Test.<init>(), line=13 bci=18

      main[1] main[1] locals
      Method arguments:
      Local variables:
      aby = instance of byte[2] (id=277)
      main[1] print aby[0]
       aby[0] = 49
      main[1] print aby[1]
       aby[1] = -68
      main[1] step
      >
      Step completed: "thread=main", Test.<init>(), line=14 bci=27

      main[1] step
      >
      Step completed: "thread=main", Test.<init>(), line=15 bci=32

      main[1] locals
      Method arguments:
      Local variables:
      aby = instance of byte[2] (id=277)
      str = "1?"
      by2 = instance of byte[2] (id=281)
      main[1] print by2[0]
       by2[0] = 49
      main[1] print by2[1]
       by2[1] = -68
      main[1] exit

      Notice that after the conversion the values are correct. Windows gives the same results as well, (it works). The wierd thing is that both programs ran off of the same sdk so I figured it must be an os library issue, but after updating the patches on the Solaris 8 box it didn't fix the problem, hence I am opening up this bug report.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      To reproduce run the test program that I have included and step through the results and watch the values change. Make sure it is Solaris 8 on sparc as it works on Solaris 9 on sparc and under windows. I haven't test it under linux or intel Solaris.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I would expect the results to be what I got in the second debug case under solaris 9 where the value shows up as -68 as it should. Converting a byte[] to a String back to a byte[] should yield the same result.
      ACTUAL -
      The result is that all my negatives become 63.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      There is no error message.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Test {
          public Test() {
              byte[] aby = new byte[] { 0x31, (byte)0xBC };
              String str = new String(aby);
              byte[] by2 = str.getBytes();
          }

          public static void main(String[] args) {
              Test test1 = new Test();
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      My work around to maintain Solaris 8 compatibility is to pass around a byte[] all the time instead of a String. This works but is inconvient.
      ###@###.### 2005-1-21 01:44:09 GMT

            martin Martin Buchholz
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: