Name: rmT116609 Date: 12/10/2003
FULL PRODUCT VERSION :
java version "1.4.2_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_01-b06)
Java HotSpot(TM) Client VM (build 1.4.2_01-b06, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux mattias-laptop 2.4.20 #4 SMP Fri Aug 8 09:48:27 CEST 2003 i686 i686 i386 GNU/Linux
(This Linux installation is a RedHat 9 with a modified kernel).
Windows 2000
A DESCRIPTION OF THE PROBLEM :
Under some (unclear) circumstances NullPointerExceptions can be thrown without any stacktrace. This makes the error handling within our system difficult. (The fact that the NullPointerException is thrown is not the bug - this is expected behaviour)
This only seems to happen when the JVM is run with "-server" option.
For more details on the problem see "Steps to Reproduce" below
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
I have managed to create a small testcase that reproduces the issue. There is one Makefile and a source file "StackTraceTest.java". I am pasting them below as text (ie in the "Source code..." entry).
With these files
1. Place the files in the current directory
2. Make sure JAVA_HOME environment variable is set
3. Run "make"
4. Run "make runtest"
One strange effect I noted was that if the line "import java.lang.reflect.*;" was removed from the test program, the problem seems to happen later (ie after about 6000 testruns instead of 2000). Should this even affect the generated class file in any way??
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The NullPointerException should always include stacktrace.
ACTUAL -
After a number of Ok testruns by the program (typically around 2000), the test results in a NullPointerException with no stacktrace. After the first failure, all subsequent runs seem to fail as well.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
...
****** validation failed. Thread 100, test run 9, total count 2181
java.lang.NullPointerException
****** validation failed. Thread 37, test run 23, total count 2182
java.lang.NullPointerException
****** validation failed. Thread 38, test run 23, total count 2183
java.lang.NullPointerException
...
Note the lack of stacktrace on the NullPointerExceptions.
REPRODUCIBILITY :
This bug can be reproduced often.
---------- BEGIN SOURCE ----------
================== StackTraceTest.java =================
import java.lang.reflect.*;
import java.io.*;
import java.util.*;
public class StackTraceTest extends Thread
{
public static void main( String[] args )
throws Exception {
System.out.println("Starting...");
int threadCount = 100;
int testCount = 100;
StackTraceTest[] tests =
new StackTraceTest[ threadCount ];
for( int i=0; i<threadCount; ++i ) {
tests[i] = new StackTraceTest();
}
for( int j=0; j<tests.length; ++j ) {
tests[j].start();
}
for( int i=0; i<testCount; ++i ) {
for( int j=0; j<tests.length; ++j ) {
tests[j].addAction( RUN_TEST );
}
}
for( int j=0; j<tests.length; ++j ) {
tests[j].addAction( EXIT );
}
}
private final static int NO_ACTION = 0;
private final static int RUN_TEST = 1;
private final static int EXIT = 2;
private LinkedList _actionList = new LinkedList();
private static int threadIdCounter = 0;
private static synchronized int getThreadId() {
return ++threadIdCounter;
}
private int _threadId = getThreadId();
private int _testCount = 0;
public void run() {
int action;
do {
action = getAction();
if( action == RUN_TEST ) {
test(null);
}
try {
// Wait 1/10 sec
synchronized( this ) {
wait(100);
}
} catch( InterruptedException ignored ) {}
} while( action != EXIT );
}
private synchronized int getAction() {
if( _actionList.isEmpty() ) {
return NO_ACTION;
} else {
return ((Integer)_actionList.removeFirst()).intValue();
}
}
public synchronized void addAction( int action ) {
_actionList.addLast( new Integer(action));
notify();
}
private static String _refResult = null;
private static int _totalTestCount = 0;
private static synchronized void validateResult(
String result, int threadId, int testCount ) {
++_totalTestCount;
if( _totalTestCount % 1000 == 0 ) {
System.out.println( "Total Count: "+_totalTestCount );
}
if( _refResult == null ) {
_refResult = result;
} else {
if( ! _refResult.equals( result )) {
System.out.println("****** validation failed. Thread "+
threadId+", test run "+testCount+
", total count "+_totalTestCount);
System.out.println(result);
}
}
}
public void test( String s ) {
++_testCount;
try {
"ABC".startsWith( s );
}
catch( Exception e ) {
StringWriter sout = new StringWriter();
e.printStackTrace(new PrintWriter(sout));
String result = sout.toString();
validateResult( result, _threadId, _testCount );
}
}
}
=============== Makefile ========================
StackTraceTest.class: StackTraceTest.java
$(JAVA_HOME)/bin/javac $^
runtest:
$(JAVA_HOME)/bin/java -server -cp . StackTraceTest
runtest_client:
$(JAVA_HOME)/bin/java -client -cp . StackTraceTest
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Run JVM without "-server" flag
(Incident Review ID: 230192)
======================================================================