Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

array length changes in openjdk

I've recently seen strange behaviour in my application that I can't really explain. They occur very unfrequent so I can't reproduce them. While the place where these problems occur changes, the common part seems to be that an array changes size after it has been created (I know, this is not possible, hence: strange behaviour).

A couple of examples to make my point clear:

java.lang.StringIndexOutOfBoundsException: String index out of range: 86
    at java.lang.String.checkBounds(String.java:409)
    at java.lang.String.<init>(String.java:577)
    at com.acunia.fleet.diagnostics.providers.tacho.VDOKLineInputParser.getRealDriverID(Unknown Source)

The code that would cause this:

public String getRealDriverID(byte[] buffer) {
  if (buffer.length > 86 && isDriverCardInserted(buffer)) {
    return new String(buffer, 70, 16);
  }   
  return null;
}

So we first check that the buffer is big enough (more than 86 bytes) before trying to create a String from them.

A second example:

java.lang.ArrayIndexOutOfBoundsException: -1
    at java.lang.String.lastIndexOf(String.java:1889)
    at java.lang.String.lastIndexOf(String.java:1835)
    at java.lang.String.lastIndexOf(String.java:1817)
    at com.acunia.service.position.nmea.comm.CommPositionProvider.isValid(Unknown Source)

The line that causes this exception is:

int csi = line.lastIndexOf("*");

I had a look at the openjdk String.java source, but couldn't find a fault unless arrays could suddenly start changing size after they where created.

The only reference online that I could find that might be related was as a openjdk bug: https://bugs.openjdk.java.net/browse/JDK-6817012. This bug was marked a 'not an issue' though, although when reading this I can't really tell if the problem that is mentioned is not recognized as a bug, or if the person who closed the bug doesn't see why this bug would cause problems.

If anyone has ever encountered a similar problem I would really appreciate hearing about it. As it stands the problem is too unstable to attempt to fix it by using other versions of openjdk.

Problem was seen on:

hardware: custom arm platform
java version "1.6.0_31"
OpenJDK Runtime Environment (IcedTea6 1.13.3) (6b31-1.13.3-1~deb7u1)
OpenJDK Zero VM (build 23.25-b01, mixed mode)
Linux 3.2.0 #1 Fri Jun 20 10:25:16 CEST 2014 armv7l GNU/Linux
like image 262
David Calvo Avatar asked May 11 '15 12:05

David Calvo


People also ask

Is array size fixed in Java?

The length of an array is established when the array is created. After creation, its length is fixed.

Can you change the size of allocated arrays?

If you create an array by initializing its values directly, the size will be the number of elements in it. Thus the size of the array is determined at the time of its creation or, initialization once it is done you cannot change the size of the array.

How do you make an array longer in Java?

Increase the Array Size Using the Arrays. copyOf() Method in Java. Java has a built-in copyOf() method that can create a new array of a larger size and copy our old array elements into the new one.


2 Answers

This is most likely an issue with the bytes and the system charset. The documentation explicitly says:

The behavior of this constructor when the given bytes are not valid in the default charset is unspecified.

You can circumvent this by explicitly providing the correct charset:

new String(buffer, 70, 16, StandardCharsets.UTF_8)
like image 102
aioobe Avatar answered Sep 25 '22 10:09

aioobe


You are creating the new String using byte[] array without specifying the Charset. Thus my guess is that system default charset got changed and you see the behaviour changes. I'd suggest to always specify the charset explicitly. For example:

return new String(buffer, 70, 16, "UTF-8");
like image 23
Tagir Valeev Avatar answered Sep 22 '22 10:09

Tagir Valeev