You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@netbeans.apache.org by GitBox <gi...@apache.org> on 2018/11/11 14:47:06 UTC

[GitHub] matthiasblaesing closed pull request #1000: [NETBEANS-583] Avoid errors related to ClosedByInterruptException

matthiasblaesing closed pull request #1000: [NETBEANS-583] Avoid errors related to ClosedByInterruptException
URL: https://github.com/apache/incubator-netbeans/pull/1000
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/platform/core.netigso/nbproject/project.xml b/platform/core.netigso/nbproject/project.xml
index 9e8cee0841..3ad71685cc 100644
--- a/platform/core.netigso/nbproject/project.xml
+++ b/platform/core.netigso/nbproject/project.xml
@@ -72,7 +72,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java b/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
index 6efa82cc65..56af0bd829 100644
--- a/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
+++ b/platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
@@ -25,7 +25,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.security.ProtectionDomain;
 import java.util.Arrays;
@@ -56,6 +55,7 @@
 import org.openide.modules.Places;
 import org.openide.util.*;
 import org.openide.util.NbBundle.Messages;
+import org.openide.util.io.FilesNI;
 import org.openide.util.lookup.ServiceProvider;
 import org.openide.util.lookup.ServiceProviders;
 import org.osgi.framework.Bundle;
@@ -468,7 +468,7 @@ private void fakeOneModule(Module m, Bundle original) throws IOException {
             } else if (symbolicName != null) { // NOI18N
                 if (original != null) {
                     LOG.log(Level.FINE, "Updating bundle {0}", original.getLocation());
-                    try (InputStream is = Files.newInputStream(m.getJarFile().toPath())) {
+                    try (InputStream is = FilesNI.newInputStream(m.getJarFile())) {
                         original.update(is);
                     } catch (InvalidPathException ex) {
                         throw new IOException(ex);
diff --git a/platform/core.network/nbproject/project.xml b/platform/core.network/nbproject/project.xml
index 0fe2742bcc..bdcef32bf0 100644
--- a/platform/core.network/nbproject/project.xml
+++ b/platform/core.network/nbproject/project.xml
@@ -106,7 +106,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java b/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
index 440ff507c6..9ff9eba25c 100644
--- a/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
+++ b/platform/core.network/src/org/netbeans/core/network/proxy/NbProxySelector.java
@@ -24,8 +24,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.*;
-import java.nio.file.Files;
-import java.nio.file.Paths;
 import java.util.*;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -35,6 +33,7 @@
 import java.util.regex.PatternSyntaxException;
 import org.netbeans.core.ProxySettings;
 import org.openide.util.RequestProcessor;
+import org.openide.util.io.FilesNI;
 import org.openide.util.lookup.ServiceProvider;
 
 /**
@@ -422,7 +421,7 @@ static boolean useSystemProxies() {
                 }
 
                 fname = netProperties.getCanonicalPath();
-                try (InputStream bin = new BufferedInputStream(Files.newInputStream(Paths.get(fname)))) {
+                try (InputStream bin = new BufferedInputStream(FilesNI.newInputStream(new File(fname)))) {
                     props.load(bin);
                 }
 
diff --git a/platform/core.network/src/org/netbeans/core/network/proxy/kde/KdeNetworkProxy.java b/platform/core.network/src/org/netbeans/core/network/proxy/kde/KdeNetworkProxy.java
index 505fb9a8b7..887002afb1 100644
--- a/platform/core.network/src/org/netbeans/core/network/proxy/kde/KdeNetworkProxy.java
+++ b/platform/core.network/src/org/netbeans/core/network/proxy/kde/KdeNetworkProxy.java
@@ -20,9 +20,7 @@
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.HashMap;
 import java.util.Map;
@@ -30,6 +28,7 @@
 import java.util.logging.Logger;
 import org.netbeans.core.network.proxy.NetworkProxyResolver;
 import org.netbeans.core.network.proxy.NetworkProxySettings;
+import org.openide.util.io.FilesNI;
 
 /**
  *
@@ -132,7 +131,7 @@ public NetworkProxySettings getNetworkProxySettings() {
         Map<String, String> map = new HashMap<String, String>();
 
         if (kioslavercFile.exists()) {
-            try (BufferedReader br = Files.newBufferedReader(kioslavercFile.toPath())) {
+            try (BufferedReader br = FilesNI.newBufferedReader(kioslavercFile)) {
                 String line;
                 boolean inGroup = false;
                 while ((line = br.readLine()) != null) {
diff --git a/platform/core.osgi/nbproject/project.xml b/platform/core.osgi/nbproject/project.xml
index f83edc3ddf..7ba05c3725 100644
--- a/platform/core.osgi/nbproject/project.xml
+++ b/platform/core.osgi/nbproject/project.xml
@@ -76,7 +76,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.osgi/src/org/netbeans/core/osgi/OSGiInstalledFileLocator.java b/platform/core.osgi/src/org/netbeans/core/osgi/OSGiInstalledFileLocator.java
index bfc9a960c0..42b73530a1 100644
--- a/platform/core.osgi/src/org/netbeans/core/osgi/OSGiInstalledFileLocator.java
+++ b/platform/core.osgi/src/org/netbeans/core/osgi/OSGiInstalledFileLocator.java
@@ -25,7 +25,6 @@
 import java.io.OutputStream;
 import java.net.URI;
 import java.net.URL;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.Arrays;
 import java.util.Collections;
@@ -36,6 +35,7 @@
 import org.openide.util.NbBundle;
 import org.openide.util.NbCollections;
 import org.openide.util.Utilities;
+import org.openide.util.io.FilesNI;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -124,7 +124,7 @@ public OSGiInstalledFileLocator(BundleContext context) {
                             throw new IOException("Could not make " + dir);
                         }
                         try (InputStream is = resource.openStream();
-                                OutputStream os = Files.newOutputStream(f2.toPath())) {
+                                OutputStream os = FilesNI.newOutputStream(f2)) {
                             byte[] buf = new byte[4096];
                             int read;
                             while ((read = is.read(buf)) != -1) {
diff --git a/platform/core.output2/nbproject/project.xml b/platform/core.output2/nbproject/project.xml
index 38843bb2bb..a27d2873c4 100644
--- a/platform/core.output2/nbproject/project.xml
+++ b/platform/core.output2/nbproject/project.xml
@@ -111,7 +111,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.output2/src/org/netbeans/core/output2/Controller.java b/platform/core.output2/src/org/netbeans/core/output2/Controller.java
index 806fae907b..9c5045545a 100644
--- a/platform/core.output2/src/org/netbeans/core/output2/Controller.java
+++ b/platform/core.output2/src/org/netbeans/core/output2/Controller.java
@@ -26,7 +26,6 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.lang.ref.WeakReference;
-import java.nio.file.Files;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -41,6 +40,7 @@
 import javax.swing.text.Document;
 import org.netbeans.core.output2.options.OutputOptions;
 import org.openide.util.Exceptions;
+import org.openide.util.io.FilesNI;
 import org.openide.windows.IOColors;
 import org.openide.windows.IOContainer;
 import org.openide.windows.IOSelect;
@@ -525,7 +525,7 @@ private static OutputStream getLogStream() {
                         f.delete();
                     }
                     f.createNewFile();
-                    logStream = Files.newOutputStream(f.toPath());
+                    logStream = FilesNI.newOutputStream(f);
                 } catch (Exception e) {
                     e.printStackTrace();
                     logStream = System.err;
diff --git a/platform/core.startup.base/nbproject/project.xml b/platform/core.startup.base/nbproject/project.xml
index 6b3ea5d69c..fc6b1037f1 100644
--- a/platform/core.startup.base/nbproject/project.xml
+++ b/platform/core.startup.base/nbproject/project.xml
@@ -46,7 +46,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.startup.base/src/org/netbeans/core/startup/layers/ArchiveURLMapper.java b/platform/core.startup.base/src/org/netbeans/core/startup/layers/ArchiveURLMapper.java
index bc308cea75..4adb4b09bd 100644
--- a/platform/core.startup.base/src/org/netbeans/core/startup/layers/ArchiveURLMapper.java
+++ b/platform/core.startup.base/src/org/netbeans/core/startup/layers/ArchiveURLMapper.java
@@ -29,7 +29,6 @@
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLDecoder;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.Enumeration;
 import java.util.HashMap;
@@ -48,6 +47,7 @@
 import org.openide.filesystems.Repository;
 import org.openide.filesystems.URLMapper;
 import org.openide.util.BaseUtilities;
+import org.openide.util.io.FilesNI;
 import org.openide.util.lookup.ServiceProvider;
 
 @ServiceProvider(service=URLMapper.class)
@@ -242,7 +242,9 @@ private static File copyJAR(FileObject fo, URI archiveFileURI, boolean replace)
                     copy = copy.getCanonicalFile();
                     copy.deleteOnExit();
                 }
-                try (InputStream is = fo.getInputStream(); OutputStream os = Files.newOutputStream(copy.toPath())) {
+                try (InputStream is = fo.getInputStream();
+                        OutputStream os = FilesNI.newOutputStream(copy))
+                {
                     FileUtil.copy(is, os);
                 } catch (InvalidPathException ex) {
                     throw new IOException(ex);
diff --git a/platform/core.startup.base/src/org/netbeans/core/startup/layers/NbinstURLStreamHandler.java b/platform/core.startup.base/src/org/netbeans/core/startup/layers/NbinstURLStreamHandler.java
index db3899b8ce..a6c2046950 100644
--- a/platform/core.startup.base/src/org/netbeans/core/startup/layers/NbinstURLStreamHandler.java
+++ b/platform/core.startup.base/src/org/netbeans/core/startup/layers/NbinstURLStreamHandler.java
@@ -28,12 +28,12 @@
 import java.net.URLConnection;
 import java.net.URLStreamHandler;
 import java.net.UnknownServiceException;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import org.openide.filesystems.FileObject;
 import org.openide.filesystems.FileUtil;
 import org.openide.util.Exceptions;
 import org.openide.util.URLStreamHandlerRegistration;
+import org.openide.util.io.FilesNI;
 
 /**
  * URLStreamHandler for nbinst protocol
@@ -142,7 +142,7 @@ public InputStream getInputStream() throws IOException {
             this.connect();
             if (iStream == null) {
                 try {
-                    iStream = Files.newInputStream(f.toPath());
+                    iStream = FilesNI.newInputStream(f);
                 } catch (InvalidPathException ex) {
                     throw new IOException(ex);
                 }
diff --git a/platform/core.startup/nbproject/project.xml b/platform/core.startup/nbproject/project.xml
index 825b6b5d75..954b591ca2 100644
--- a/platform/core.startup/nbproject/project.xml
+++ b/platform/core.startup/nbproject/project.xml
@@ -63,7 +63,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/core.startup/src/org/netbeans/core/startup/logging/MessagesHandler.java b/platform/core.startup/src/org/netbeans/core/startup/logging/MessagesHandler.java
index 5f59e9a419..e5c6e926f6 100644
--- a/platform/core.startup/src/org/netbeans/core/startup/logging/MessagesHandler.java
+++ b/platform/core.startup/src/org/netbeans/core/startup/logging/MessagesHandler.java
@@ -20,13 +20,13 @@
 
 import java.io.File;
 import java.io.IOException;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.StreamHandler;
+import org.openide.util.io.FilesNI;
 
 /**
  *
@@ -85,7 +85,7 @@ private boolean checkRotate(boolean always) {
     
     private void initStream() {
         try {
-            setOutputStream(Files.newOutputStream(files[0].toPath()));
+            setOutputStream(FilesNI.newOutputStream(files[0]));
         } catch (IOException | InvalidPathException ex) {
             setOutputStream(System.err);
         }
diff --git a/platform/core.startup/src/org/netbeans/core/startup/logging/NbLogging.java b/platform/core.startup/src/org/netbeans/core/startup/logging/NbLogging.java
index 3a50fe3286..06416d8dba 100644
--- a/platform/core.startup/src/org/netbeans/core/startup/logging/NbLogging.java
+++ b/platform/core.startup/src/org/netbeans/core/startup/logging/NbLogging.java
@@ -18,17 +18,14 @@
  */
 package org.netbeans.core.startup.logging;
 
-import static java.nio.file.StandardOpenOption.APPEND;
-import static java.nio.file.StandardOpenOption.CREATE;
-
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.logging.Handler;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
+import org.openide.util.io.FilesNI;
 
 /**
  *
@@ -47,7 +44,7 @@
             try {
                 File debugLog = new File(System.getProperty("java.io.tmpdir"), "TopLogging.log"); // NOI18N
                 System.err.println("Logging sent to: " + debugLog); // NOI18N
-                _D = new PrintStream(Files.newOutputStream(debugLog.toPath(), CREATE, APPEND));
+                _D = new PrintStream(FilesNI.newOutputStream(debugLog, true));
             } catch (IOException | InvalidPathException x) {
                 x.printStackTrace();
             }
diff --git a/platform/o.n.bootstrap/nbproject/project.xml b/platform/o.n.bootstrap/nbproject/project.xml
index 3cdb325725..b4505c9d6c 100644
--- a/platform/o.n.bootstrap/nbproject/project.xml
+++ b/platform/o.n.bootstrap/nbproject/project.xml
@@ -46,7 +46,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/o.n.bootstrap/src/org/netbeans/Stamps.java b/platform/o.n.bootstrap/src/org/netbeans/Stamps.java
index e41c908977..12df31666a 100644
--- a/platform/o.n.bootstrap/src/org/netbeans/Stamps.java
+++ b/platform/o.n.bootstrap/src/org/netbeans/Stamps.java
@@ -33,7 +33,6 @@
 import java.nio.ByteOrder;
 import java.nio.MappedByteBuffer;
 import java.nio.channels.FileChannel;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.NoSuchFileException;
 import java.nio.file.StandardOpenOption;
@@ -57,6 +56,7 @@
 import org.openide.modules.Places;
 import org.openide.util.Exceptions;
 import org.openide.util.NbBundle;
+import org.openide.util.io.FilesNI;
 
 /**
  * Support for optimal checking of time stamps of certain files in
@@ -430,7 +430,7 @@ private static boolean compareAndUpdateFile(File file, String content, AtomicLon
             boolean areCachesOK;
             boolean writeFile;
             long lastMod;
-            try (InputStream is = Files.newInputStream(file.toPath())) {
+            try (InputStream is = FilesNI.newInputStream(file)) {
                 int len = is.read(read);
                 areCachesOK = len == read.length && is.available() == 0 && Arrays.equals(expected, read);
                 writeFile = !areCachesOK;
@@ -443,7 +443,7 @@ private static boolean compareAndUpdateFile(File file, String content, AtomicLon
             }
             if (writeFile) {
                 file.getParentFile().mkdirs();
-                try (OutputStream os = Files.newOutputStream(file.toPath())) {
+                try (OutputStream os = FilesNI.newOutputStream(file)) {
                     os.write(expected);
                 }
                 if (areCachesOK) {
@@ -558,7 +558,7 @@ static void checkPopulateCache() {
                 }
                 File f = new File(cache, en.getName().replace('/', File.separatorChar));
                 f.getParentFile().mkdirs();
-                try (OutputStream os = Files.newOutputStream(f.toPath())) {
+                try (OutputStream os = FilesNI.newOutputStream(f)) {
                     for (;;) {
                         int len = zip.read(arr);
                         if (len == -1) {
@@ -582,7 +582,7 @@ private static boolean clustersChanged() {
         final String clustersCache = "all-clusters.dat"; // NOI18N
         File f = fileImpl(clustersCache, null, -1); // no timestamp check
         if (f != null) {
-            try (DataInputStream dis = new DataInputStream(Files.newInputStream(f.toPath()))) {
+            try (DataInputStream dis = new DataInputStream(FilesNI.newInputStream(f))) {
                 if (Clusters.compareDirs(dis)) {
                     return false;
                 }
@@ -682,7 +682,7 @@ public boolean store(AtomicInteger delay) {
 
                 LOG.log(Level.FINE, "Storing cache {0}", cacheFile);
                 //append new entries only
-                os = Files.newOutputStream(cacheFile.toPath(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
+                os = FilesNI.newOutputStream(cacheFile, true);
                 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(this, 1024 * 1024));
                 
                 this.delay = delay;
diff --git a/platform/o.n.bootstrap/src/org/netbeans/Util.java b/platform/o.n.bootstrap/src/org/netbeans/Util.java
index cfa3e7e110..1cef7966a8 100644
--- a/platform/o.n.bootstrap/src/org/netbeans/Util.java
+++ b/platform/o.n.bootstrap/src/org/netbeans/Util.java
@@ -20,7 +20,6 @@
 package org.netbeans;
 
 import java.io.*;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.*;
 import java.util.ArrayList;
@@ -28,6 +27,7 @@
 import java.util.logging.Logger;
 import org.openide.util.*;
 import org.openide.modules.*;
+import org.openide.util.io.FilesNI;
 
 /** Static utility methods for use within this package.
  * @author Jesse Glick
@@ -61,8 +61,8 @@ static File makeTempJar(File moduleFile) throws IOException {
         String suffix = "-test.jar"; // NOI18N
         File physicalModuleFile = File.createTempFile(prefix, suffix);
         physicalModuleFile.deleteOnExit();
-        try (InputStream is = Files.newInputStream(moduleFile.toPath());
-                OutputStream os = Files.newOutputStream(physicalModuleFile.toPath())) {
+        try (InputStream is = FilesNI.newInputStream(moduleFile);
+                OutputStream os = FilesNI.newOutputStream(physicalModuleFile)) {
             byte[] buf = new byte[4096];
             int i;
             while ((i = is.read(buf)) != -1) {
diff --git a/platform/openide.filesystems/nbproject/project.xml b/platform/openide.filesystems/nbproject/project.xml
index 053ae7f1ef..950c09ad55 100644
--- a/platform/openide.filesystems/nbproject/project.xml
+++ b/platform/openide.filesystems/nbproject/project.xml
@@ -30,7 +30,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>9.3</specification-version>
+                        <specification-version>9.12</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
diff --git a/platform/openide.filesystems/src/org/openide/filesystems/JarFileSystem.java b/platform/openide.filesystems/src/org/openide/filesystems/JarFileSystem.java
index df168191f0..4b2a300bd9 100644
--- a/platform/openide.filesystems/src/org/openide/filesystems/JarFileSystem.java
+++ b/platform/openide.filesystems/src/org/openide/filesystems/JarFileSystem.java
@@ -33,7 +33,6 @@
 import java.lang.ref.Reference;
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
-import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.util.Collection;
 import java.util.Collections;
@@ -51,11 +50,11 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.zip.ZipException;
-import org.openide.util.Exceptions;
 import org.openide.util.NbBundle;
 import org.openide.util.RequestProcessor;
 import org.openide.util.RequestProcessor.Task;
 import org.openide.util.BaseUtilities;
+import org.openide.util.io.FilesNI;
 
 /** A virtual filesystem based on a JAR archive.
 * <p>For historical reasons many AbstractFileSystem.* methods are implemented
@@ -503,7 +502,8 @@ private InputStream getTemporaryInputStream(JarFile jf, JarEntry je, boolean for
         if (createContent || forceRecreate) {
             // JDK 1.3 contains bug #4336753
             //is = j.getInputStream (je);
-            try (InputStream is = getInputStream4336753(jf, je); OutputStream os = Files.newOutputStream(f.toPath())) {
+            try (InputStream is = getInputStream4336753(jf, je);
+                    OutputStream os = FilesNI.newOutputStream(f)) {
                 FileUtil.copy(is, os);
             } catch (InvalidPathException ex) {
                 throw new IOException(ex);
@@ -512,7 +512,7 @@ private InputStream getTemporaryInputStream(JarFile jf, JarEntry je, boolean for
 
         f.deleteOnExit();
 
-        return Files.newInputStream(f.toPath());
+        return FilesNI.newInputStream(f);
     }
 
     private static String temporaryName(String filePath, String entryPath) {
diff --git a/platform/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java b/platform/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java
index 7266cbfb75..beed376a28 100644
--- a/platform/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java
+++ b/platform/openide.filesystems/src/org/openide/filesystems/LocalFileSystem.java
@@ -23,9 +23,7 @@
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -40,6 +38,7 @@
 import java.util.logging.Level;
 import org.openide.util.NbBundle;
 import org.openide.util.BaseUtilities;
+import org.openide.util.io.FilesNI;
 
 /** Local filesystem. Provides access to files on local disk.
 * <p>For historical reasons many AbstractFileSystem.* methods are implemented
@@ -403,7 +402,7 @@ protected InputStream inputStream(String name) throws java.io.FileNotFoundExcept
 
         try {
             file = getFile(name);
-            fis = new BufferedInputStream(Files.newInputStream(file.toPath()));
+            fis = new BufferedInputStream(FilesNI.newInputStream(file));
         } catch (IOException | InvalidPathException exc) {
             FileNotFoundException fnfException = new FileNotFoundException(exc.getMessage());
             if ((file == null) || !file.exists()) {
@@ -423,7 +422,7 @@ protected OutputStream outputStream(final String name) throws java.io.IOExceptio
             f.getParentFile().mkdirs();
         }
         try {
-            OutputStream retVal = new BufferedOutputStream(Files.newOutputStream(f.toPath()));
+            OutputStream retVal = new BufferedOutputStream(FilesNI.newOutputStream(f));
 
             // workaround for #42624
             if (BaseUtilities.isMac()) {
diff --git a/platform/openide.util/apichanges.xml b/platform/openide.util/apichanges.xml
index a657c81be2..5e42c80cf8 100644
--- a/platform/openide.util/apichanges.xml
+++ b/platform/openide.util/apichanges.xml
@@ -26,6 +26,23 @@
         <apidef name="xml_base">XML API</apidef>
     </apidefs>
     <changes>
+    <change id="UninterruptibleNIO">
+      <api name="util_base"/>
+      <summary>Added the FilesNI utility class, relating to ClosedByInterruptException bugs</summary>
+      <version major="9" minor="12"/>
+      <date year="2018" month="10" day="31"/>
+      <author login="ebakke"/>
+      <compatibility addition="yes" binary="compatible" source="compatible" semantic="compatible"/>
+      <description>
+        <p>The utility class FilesNI (Non-Interruptible File streams) was added as a central place
+          to create file input/output streams, for cases where it may be necessary to guard against
+          a ClosedByInterruptException. The Javadoc for the class discusses and documents the issues
+          around NETBEANS-583.
+        </p>
+      </description>
+      <class package="org.openide.util.io" name="FilesNI"/>
+      <issue number="NETBEANS-583"/>
+    </change>
     <change id="weak-listen-on-specific-property">
         <api name="util_base"/>
         <summary>Weak property and vetoable listeners for a specific property name.</summary>
diff --git a/platform/openide.util/manifest.mf b/platform/openide.util/manifest.mf
index 6414c4632e..a2caecb186 100644
--- a/platform/openide.util/manifest.mf
+++ b/platform/openide.util/manifest.mf
@@ -1,5 +1,5 @@
 Manifest-Version: 1.0
 OpenIDE-Module: org.openide.util
 OpenIDE-Module-Localizing-Bundle: org/openide/util/base/Bundle.properties
-OpenIDE-Module-Specification-Version: 9.11
+OpenIDE-Module-Specification-Version: 9.12
 
diff --git a/platform/openide.util/src/org/openide/util/io/FilesNI.java b/platform/openide.util/src/org/openide/util/io/FilesNI.java
new file mode 100644
index 0000000000..77aea26858
--- /dev/null
+++ b/platform/openide.util/src/org/openide/util/io/FilesNI.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.openide.util.io;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.nio.channels.ClosedByInterruptException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import org.openide.util.RequestProcessor;
+
+/**
+ * Non-interruptible file streams. The methods in this class should be used instead of
+ * {@link Files#newInputStream(Path,OpenOption...)} or
+ * {@link Files#newOutputStream(Path,OpenOption...)} when the call site does not have a reasonable
+ * way to handle a {@link ClosedByInterruptException}, or when the expected length or frequency of
+ * individual I/O operations do not justify the extra handling logic. The file streams returned by
+ * methods in this class are guaranteed never to throw {@link ClosedByInterruptException}. Instead,
+ * they behave like the old {@link FileInputStream} and {@link FileOutputStream} classes, which do
+ * not abort when the current thread is interrupted.
+ *
+ * <p>Background: In past Java versions, heavy use of {@link FileInputStream} and
+ * {@link FileOutputStream} have been known to cause long garbage collection pauses (see
+ * <a href="https://bugs.openjdk.java.net/browse/JDK-8080225">JDK-8080225</a> and
+ * <a href="https://issues.apache.org/jira/browse/HDFS-8562">this</a> Hadoop bug). The alternative,
+ * of using NIO streams via {@link Files#newInputStream(Path,OpenOption...)} and
+ * {@link Files#newInputStream(Path,OpenOption...)}, avoids these GC problems, but introduces new
+ * backwards-incompatible behavior where individual stream operations may throw
+ * {@link ClosedByInterruptException} if the current thread is interrupted. This class serves as a
+ * single point to document and work around this problem.
+ *
+ * <p>Quite often, especially in library code that previously used FileInputStream and
+ * FileOutputStream, callers of file stream methods would have no reasonable way to handle a
+ * ClosedByInterruptException other than to retry the operation and set the current thread's
+ * interrupt bit, since its available options may be restricted by its own API contract and past
+ * behavior. For instance, allowing the {@code ClosedByInterruptException} to propagate up the stack
+ * as an {@link IOException} may be interpreted by the caller's own clients as an error rather than
+ * a normal thread interruption event, leading to the undesired display of user-level error
+ * messages. See for example <a href="https://github.com/apache/incubator-netbeans/pull/854">NETBEANS-1197</a>.
+ * The other alternative, of returning an incorrect or "empty" result, could cause problems as well,
+ * for instance if the incorrect results ends up in a cache somewhere higher up the call stack, in
+ * code that is beyond the control of the file stream client's developer. Other problematic cases
+ * include existing APIs that pass the InputStream or OutputStream on to existing, external client
+ * code. Such existing client code cannot be expected to suddenly handle a
+ * {@link ClosedByInterruptException} if it was previously never thrown.
+ *
+ * <p>Note that library code should always be prepared to handle thread interrupts gracefully, as
+ * clients of said library code may well decide to call the library from an interruptible thread.
+ * Thread interrupts arise, for instance, when code that is already running in an interrupt-enabled
+ * {@link RequestProcessor} is stopped via {@link RequestProcessor#stop()}.
+ *
+ * <p>See also the discussion on issues
+ * <a href="https://github.com/apache/incubator-netbeans/pull/854">NETBEANS-1197</a> and
+ * <a href="https://issues.apache.org/jira/browse/NETBEANS-583">NETBEANS-583</a>.
+ */
+public final class FilesNI {
+    /**
+     * Marker for currently disabled NIO-based code, kept around for illustration purposes. If we ever
+     * are to use the NIO streams here, we would need to wrap them in custom InputStream/OutputStream
+     * implementations that delegate to them, restarting operations with a regular
+     * FileInputStream/FileOutputStream in the rare case that a ClosedByInterruptException is
+     * encountered.
+     *
+     * <p>Since JDK-8080225 is fixed in JDK 10, it seems that the GC-related problems with
+     * InputStream/OutputStream will soon be going away, and so it should be fine to just always use
+     * the latter instead of the NIO streams here.
+     */
+    private static final boolean USE_NIO = false;
+
+    private FilesNI() {
+    }
+
+    /**
+     * @see FileInputStream#FileInputStream(File)
+     */
+    public static InputStream newInputStream(File file) throws IOException {
+        return USE_NIO
+            ? Files.newInputStream(file.toPath())
+            : new FileInputStream(file);
+    }
+
+    /**
+     * @see FileOutputStream#FileOutputStream(File)
+     */
+    public static OutputStream newOutputStream(File file) throws IOException {
+        return newOutputStream(file, false);
+    }
+
+    /**
+     * @see FileOutputStream#FileOutputStream(File,boolean)
+     */
+    public static OutputStream newOutputStream(File file, boolean append) throws IOException {
+        if (USE_NIO) {
+            // StandardOpenOption.CREATE is the standard behavior of "new FileOutputStream(File)".
+            return Files.newOutputStream(file.toPath(), append
+                ? new OpenOption[] { StandardOpenOption.CREATE }
+                : new OpenOption[] { StandardOpenOption.CREATE, StandardOpenOption.APPEND });
+        } else {
+            return new FileOutputStream(file, append);
+        }
+    }
+
+    /**
+     * @see Files#newBufferedReader(Path)
+     */
+    public static BufferedReader newBufferedReader(File file) throws IOException {
+        return newBufferedReader(file, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * @see Files#newBufferedReader(Path, Charset)
+     */
+    public static BufferedReader newBufferedReader(File file, Charset cs)
+        throws IOException
+    {
+        CharsetDecoder decoder = cs.newDecoder();
+        Reader reader = new InputStreamReader(newInputStream(file), decoder);
+        return new BufferedReader(reader);
+    }
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services

---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@netbeans.apache.org
For additional commands, e-mail: notifications-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists