< prev index next >

test/jdk/java/io/FileOutputStream/UnreferencedFOSClosesFd.java

Print this page
rev 50699 : 8202292: java/io/FileOutputStream/UnreferencedFOSClosesFd.java fails with "raw fd count wrong"


   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *
  26  * @test
  27  * @modules java.base/java.io:open


  28  * @bug 6524062
  29  * @summary Test to ensure that FOS.finalize() invokes the close() method as per
  30  * the specification.
  31  * @run main/othervm UnreferencedFOSClosesFd
  32  */
  33 import java.io.File;
  34 import java.io.FileDescriptor;
  35 import java.io.FileNotFoundException;
  36 import java.io.FileOutputStream;
  37 import java.io.IOException;
  38 import java.lang.management.ManagementFactory;
  39 import java.lang.management.OperatingSystemMXBean;
  40 import java.lang.ref.Reference;
  41 import java.lang.ref.ReferenceQueue;
  42 import java.lang.ref.WeakReference;
  43 import java.lang.reflect.Field;


  44 import java.util.HashSet;
  45 import java.util.concurrent.atomic.AtomicInteger;
  46 
  47 import com.sun.management.UnixOperatingSystemMXBean;
  48 


  49 public class UnreferencedFOSClosesFd {
  50 
  51     enum CleanupType {
  52         CLOSE,      // Cleanup is handled via calling close
  53         CLEANER}    // Cleanup is handled via Cleaner
  54 
  55     static final String FILE_NAME = "empty.txt";
  56 
  57     /**
  58      * Subclass w/ no overrides; not finalize or close.
  59      * Cleanup should be via the Cleaner (not close).
  60      */
  61     public static class StreamOverrides extends FileOutputStream {
  62 
  63         protected final AtomicInteger closeCounter;
  64 
  65         public StreamOverrides(String name) throws FileNotFoundException {
  66             super(name);
  67             closeCounter = new AtomicInteger(0);
  68         }


 116 
 117         @SuppressWarnings({"deprecation","removal"})
 118         protected void finalize() throws IOException {
 119             super.finalize();
 120         }
 121     }
 122 
 123     /**
 124      * Main runs each test case and reports number of failures.
 125      */
 126     public static void main(String argv[]) throws Exception {
 127 
 128 
 129 
 130         File inFile = new File(System.getProperty("test.dir", "."), FILE_NAME);
 131         inFile.createNewFile();
 132         inFile.deleteOnExit();
 133 
 134         String name = inFile.getPath();
 135 

 136         long fdCount0 = getFdCount();
 137         System.out.printf("initial count of open file descriptors: %d%n", fdCount0);
 138 
 139         int failCount = 0;
 140         failCount += test(new FileOutputStream(name), CleanupType.CLEANER);
 141 
 142         failCount += test(new StreamOverrides(name), CleanupType.CLEANER);
 143 
 144         failCount += test(new StreamOverridesClose(name), CleanupType.CLOSE);
 145 
 146         failCount += test(new StreamOverridesFinalize(name), CleanupType.CLEANER);
 147 
 148         failCount += test(new StreamOverridesFinalizeClose(name), CleanupType.CLOSE);
 149 
 150         if (failCount > 0) {
 151             throw new AssertionError("Failed test count: " + failCount);
 152         }
 153 
 154         // Check the final count of open file descriptors
 155         long fdCount = getFdCount();
 156         System.out.printf("final count of open file descriptors: %d%n", fdCount);
 157         if (fdCount != fdCount0) {
 158             throw new AssertionError("raw fd count wrong: expected: " + fdCount0
 159             + ", actual: " + fdCount);

 160         }
 161     }
 162 
 163     // Get the count of open file descriptors, or -1 if not available
 164     private static long getFdCount() {
 165         OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
 166         return  (mxBean instanceof UnixOperatingSystemMXBean)
 167                 ? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
 168                 : -1L;
 169     }
 170 
 171     private static int test(FileOutputStream fos, CleanupType cleanType) throws Exception {
 172 
 173         try {
 174             System.out.printf("%nTesting %s%n", fos.getClass().getName());
 175 
 176             // Prepare to wait for FOS to be reclaimed
 177             ReferenceQueue<Object> queue = new ReferenceQueue<>();
 178             HashSet<Reference<?>> pending = new HashSet<>();
 179             WeakReference<FileOutputStream> msWeak = new WeakReference<>(fos, queue);




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /**
  25  *
  26  * @test
  27  * @modules java.base/java.io:open
  28  * @library /test/lib
  29  * @build jdk.test.lib.util.FileUtils UnreferencedFOSClosesFd
  30  * @bug 6524062
  31  * @summary Test to ensure that FOS.finalize() invokes the close() method as per
  32  * the specification.
  33  * @run main/othervm UnreferencedFOSClosesFd
  34  */
  35 import java.io.File;
  36 import java.io.FileDescriptor;
  37 import java.io.FileNotFoundException;
  38 import java.io.FileOutputStream;
  39 import java.io.IOException;
  40 import java.lang.management.ManagementFactory;
  41 import java.lang.management.OperatingSystemMXBean;
  42 import java.lang.ref.Reference;
  43 import java.lang.ref.ReferenceQueue;
  44 import java.lang.ref.WeakReference;
  45 import java.lang.reflect.Field;
  46 import java.nio.file.Path;
  47 import java.util.ArrayDeque;
  48 import java.util.HashSet;
  49 import java.util.concurrent.atomic.AtomicInteger;
  50 
  51 import com.sun.management.UnixOperatingSystemMXBean;
  52 
  53 import jdk.test.lib.util.FileUtils;
  54 
  55 public class UnreferencedFOSClosesFd {
  56 
  57     enum CleanupType {
  58         CLOSE,      // Cleanup is handled via calling close
  59         CLEANER}    // Cleanup is handled via Cleaner
  60 
  61     static final String FILE_NAME = "empty.txt";
  62 
  63     /**
  64      * Subclass w/ no overrides; not finalize or close.
  65      * Cleanup should be via the Cleaner (not close).
  66      */
  67     public static class StreamOverrides extends FileOutputStream {
  68 
  69         protected final AtomicInteger closeCounter;
  70 
  71         public StreamOverrides(String name) throws FileNotFoundException {
  72             super(name);
  73             closeCounter = new AtomicInteger(0);
  74         }


 122 
 123         @SuppressWarnings({"deprecation","removal"})
 124         protected void finalize() throws IOException {
 125             super.finalize();
 126         }
 127     }
 128 
 129     /**
 130      * Main runs each test case and reports number of failures.
 131      */
 132     public static void main(String argv[]) throws Exception {
 133 
 134 
 135 
 136         File inFile = new File(System.getProperty("test.dir", "."), FILE_NAME);
 137         inFile.createNewFile();
 138         inFile.deleteOnExit();
 139 
 140         String name = inFile.getPath();
 141 
 142         FileUtils.listFileDescriptors(System.out);
 143         long fdCount0 = getFdCount();

 144 
 145         int failCount = 0;
 146         failCount += test(new FileOutputStream(name), CleanupType.CLEANER);
 147 
 148         failCount += test(new StreamOverrides(name), CleanupType.CLEANER);
 149 
 150         failCount += test(new StreamOverridesClose(name), CleanupType.CLOSE);
 151 
 152         failCount += test(new StreamOverridesFinalize(name), CleanupType.CLEANER);
 153 
 154         failCount += test(new StreamOverridesFinalizeClose(name), CleanupType.CLOSE);
 155 
 156         if (failCount > 0) {
 157             throw new AssertionError("Failed test count: " + failCount);
 158         }
 159 
 160         // Check the final count of open file descriptors
 161         long fdCount = getFdCount();

 162         if (fdCount != fdCount0) {
 163             System.out.printf("initial count of open file descriptors: %d%n", fdCount0);
 164             System.out.printf("final count of open file descriptors: %d%n", fdCount);
 165             FileUtils.listFileDescriptors(System.out);
 166         }
 167     }
 168 
 169     // Get the count of open file descriptors, or -1 if not available
 170     private static long getFdCount() {
 171         OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
 172         return  (mxBean instanceof UnixOperatingSystemMXBean)
 173                 ? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
 174                 : -1L;
 175     }
 176 
 177     private static int test(FileOutputStream fos, CleanupType cleanType) throws Exception {
 178 
 179         try {
 180             System.out.printf("%nTesting %s%n", fos.getClass().getName());
 181 
 182             // Prepare to wait for FOS to be reclaimed
 183             ReferenceQueue<Object> queue = new ReferenceQueue<>();
 184             HashSet<Reference<?>> pending = new HashSet<>();
 185             WeakReference<FileOutputStream> msWeak = new WeakReference<>(fos, queue);


< prev index next >