Java Bugs

Last updated November 8, 2003

TopCoder uses JDK 1.4.1_04 on Linux 2.4, with the command-line options -client -Xmx64m. I compiled this list from the release notes for this version and subsequent versions. There may be known bugs that were not listed in the release notes, as well as unknown bugs.

Bugs were excluded if I didn't think they could possibly be relevant in a TopCoder competition. I was pretty conservative, but I want to emphasize that I make no guarantees whatsoever about the accuracy or completeness of this information.

Double to Long Conversions of NaN Values

Bug Parade: 4755500

Summary Description: If NaN values of type double are converted to type long, future conversions from double to long may yield 0, regardless of the actual double value. Math.round() converts from double to long internally, so passing it NaN values will invoke this bug.

Workaround: Do not convert double NaN values to long values. If necessary, wrap double to long conversions in a test, such as Double.isNaN(x) ? 0 : (long) x, where x has type double.

BigInteger.isProbablePrime()

Bug Parade: 4624738

Summary Description: For some prime numbers, BigInteger.isProbablePrime() returns false. Note that it should never return false for a prime number, but may return true for a composite number extremely rarely.

Workaround: Write your own Miller-Rabin and Lucas-Lehmer tests.

Pathological Use of jsr and ret

Bug Parade: 4702051

Summary Description: Pathological use of jsr and ret may cause hotspot to crash, or at least to use pathological amounts of time and memory.

Workaround: Don't write code that nests try blocks pathologically.

StringBuffer Memory Leak

Bug Parade: 4724129

Summary Description: StringBuffer has a so-called memory leak. IMHO, some people just had a problem with the particular way that the underlying character array was shared between StringBuffers and Strings.

Workaround: Be aware that a String created from a StringBuffer may consume as much memory as the StringBuffer, even if the StringBuffer is garbage-collected. Call String.intern() to avoid this.

Bytecode Verification of Arrays of Arrays

Bug Parade: 4368664

Summary Description: It's pretty easy to write code using arrays of arrays such that javac will produce class files that don't pass bytecode verification. Sun's developers can't seem to agree on whether the problem lies with the compiler or the verifier. Contrary to the Bug Parade report, this bug is not fixed (although the particular case in the report now works). I don't trust Sun's toolchain in the least as far as this issue goes.

Workaround: Fortunately, code that could run into this problem should cause a run-time exception anyway, so it shouldn't be much of an issue. If you're doing something weird, like deliberately catching ArrayStoreException in cases involving arrays of arrays, run it at least once on TopCoder's servers to make sure it passes bytecode verification.

Implicit Narrowing Conversions in Return Statements

Article: The Implicit Narrowing of Integer Constants

Summary Description: This article, pointed out by dplass, notes that there is an ambiguity in the Java Language Specification regarding which expressions are legal in return statements. The JLS states that “The type T [of the expression] must be assignable (§5.2) to the declared result type of the method.” However, the types alone are not sufficient to determine assignability under §5.2 in all cases. §5.2 does not specify, e.g., whether type int is assignable to type short, but rather specifies that the values of some expressions of type int are assignable to type short, and others are not. As actually implemented, an expression is legal in a return statement if, and only if, it would be legal to assign the expression to a variable whose type is the declared result type of the method under §5.2.

Workaround: I think the actual implementation is what most people would expect (i.e., byte foo() { return 100; } is legal. It is still, strictly speaking, an ambiguity.

Code That Exceeds JVM Limits

Bug Parade: 4309152

Summary Description: Javac will generate class files that exceed various JVM limits (number of method arguments, size of bytecode for a method, number of array dimensions, etc.), without giving a warning that it has done so. The JVM will not be able to load the class.

Workaround: If you've written some horrendous class that might exceed a JVM limit, run it at least once on TopCoder's servers to make sure that it doesn't.