JDK-6526376 : DeleteOnExitHook.add() produces NullPointerException
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 6,6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: linux,windows,windows_xp
  • CPU: x86
  • Submitted: 2007-02-19
  • Updated: 2011-05-17
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u21Fixed 7 b10Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Last time I create a lot of console tests that intensively use temporary files, created by File.createTempFile + deleteOnExit() methods. Several times, when I broke them by Ctrl+C combination, I detected the following error message (after pressing Ctrl+C):

java.lang.NullPointerException
        at java.io.DeleteOnExitHook.add(DeleteOnExitHook.java:33)
        at java.io.File.deleteOnExit(File.java:939)

Unfortunately, it is not too easy to reproduce this bug, but I've looked at JDK source text and seen the following code in DeleteOnExitHook.java:
    ......
    static void add(String file) {
	synchronized(files) {
	    if(files == null)
		throw new IllegalStateException("Shutdown in progress");

	    files.add(file);
	}
    }
    ......

The line #33 is "synchronized(files) {".

I think here is a little error. What is the sense to check "if(files == null)" after this "synchronized" operator? If "files" field really contains null, the "synchronized" operator will produce NullPointerException. It means that IllegalStateException will be never thrown here.

Moreover, why is this situation detected as an exception at all? If the user presses Ctrl+C, and the DeleteOnExitHook instance (scheduled by "sun.misc.SharedSecrets.setJavaIODeleteOnExitAccess" call at the end of "File.java") starts its "run()" method (which contains "files = null" operator), the basic application thread may call "deleteOnExit()" method one or two times more. Why should the user see an exception at the console or logs in this situation? How this message will help the user to delete files that were not automatically deleted?

Maybe, it is possible to implement more complex logic, when the files added to DeleteOnExitHook while termination process will be though deleted?

REGRESSION.  Last worked in version mustang

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run any long-time console test which creates temporary files very often, with calling "deleteOnExit()" method of File class for each created file. Click Ctrl+C while running this test.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
All files, for which "deleteOnExit()" was called, should be successfully deleted. Or, maybe, some files stay existing with very low probability, but no error messages are printed to the console.
ACTUAL -
The user see a strange message about NullPointerException after Ctrl+C and think that my console application contains a serious bug.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.NullPointerException
        at java.io.DeleteOnExitHook.add(DeleteOnExitHook.java:33)
        at java.io.File.deleteOnExit(File.java:939)


REPRODUCIBILITY :
This bug can be reproduced rarely.

Release Regression From : 6
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Release Regression From : 6
The above release value was the last known release where this 
bug was not reproducible. Since then there has been a regression.

Comments
EVALUATION There is an issue in java.io.DeleteOnExitHook.add whereby if you try to mark a file as deleteOnExit while the vm is being shutdown and the DeleteOnExitHook is running, you will get a NPE. The fix is to synchronize on the class itself and not the 'files' static field. *** (#1 of 1): [ UNSAVED ] ###@###.###
05-03-2007