Duplicate :
|
|
Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
OPERATING SYSTEM Windows XP FULL JDK VERSION java version "1.5.0_04" Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_04-b05) Java HotSpot(TM) Client VM (build 1.5.0_04-b05, mixed mode) DESCRIPTION The problem relates to the use of the api constructor method FileInputStream(FileDescriptor), in combination with the class's getFD() method and its finalizer method. The constructor creates a new FileInputStream Object based on an existing FileDescriptor Object. By first creating a FileInputStream using a different constructor, and then calling getFD(), the FileInputStream(FileDescriptor) constructor can be used to create another FileInputStream. This means we have two FileInputStreams using the same FileDescriptor class, and so the same native fd. If one of these objects hten becomes eligible for gc, the finalizer can run, which will close the native fd, even though the other FileInputStream object is still using it. A testcase that reproduces this problem is specified below: ============== import java.io.*; public class FIS { public static void main(String[] args) { try { /*Create initial FIS for file */ FileInputStream fis1 = new FileInputStream("thefile.txt"); /* Get the FileDescriptor from the fis */ FileDescriptor fd = fis1.getFD(); /* Create a new FIS based on the existing FD (so the two FIS's share the same native fd) */ FileInputStream fis2 = new FileInputStream(fd); /* allow fis1 to be gc'ed */ fis1 = null; int ret = 0; while(ret >= 0) { /* encourage gc */ System.gc(); /* read from fis2 - when fis1 is gc'ed and finalizer is run, read will fail */ System.out.println("about to read"); ret = fis2.read(); } } catch (Exception e) { e.printStackTrace(); } } } =============== This would be a problem whenever a FileDescripter from any existing Stream is passed into a FileInputStream or in fact to any Stream which has a constructor that takes a FileDescriptor and has a finalizer that closes the fd (i.e. FileOutputStream would have the same problem.) This looks like an api issue. The finalizer seems a sensible thing to have, so that if we forget to close the FileInputStream, it (and the native fd) are closed at some point. However, this logic requires that a native fd is uniquely associated with a single stream, but this is not guaranteed when you can create a FileInputStream based on an existing FileDescriptor object(and so existing native fd).
|