Index: tika-core/src/main/java/org/apache/tika/fork/ForkClient.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- tika-core/src/main/java/org/apache/tika/fork/ForkClient.java	(revision 1703352)
+++ tika-core/src/main/java/org/apache/tika/fork/ForkClient.java	(revision )
@@ -16,33 +16,29 @@
  */
 package org.apache.tika.fork;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.NotSerializableException;
+import org.apache.tika.exception.TikaException;
+import org.apache.tika.io.IOUtils;
+import org.xml.sax.ContentHandler;
+
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.zip.ZipEntry;
 
-import org.apache.tika.exception.TikaException;
-import org.apache.tika.io.IOUtils;
-import org.xml.sax.ContentHandler;
-
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 class ForkClient {
 
-    private final List<ForkResource> resources = new ArrayList<ForkResource>();
+    private static final Path jar = createBootstrapJar();
 
+    private final List<ForkResource> resources = new ArrayList<>();
+
     private final ClassLoader loader;
 
-    private final File jar;
-
     private final Process process;
 
     private final DataOutputStream output;
@@ -56,13 +52,11 @@
         boolean ok = false;
         try {
             this.loader = loader;
-            this.jar = createBootstrapJar();
 
             ProcessBuilder builder = new ProcessBuilder();
-            List<String> command = new ArrayList<String>();
-            command.addAll(java);
+            List<String> command = new ArrayList<>(java);
             command.add("-jar");
-            command.add(jar.getPath());
+            command.add(jar.toString());
             builder.command(command);
             this.process = builder.start();
 
@@ -116,11 +110,11 @@
 
     public synchronized Throwable call(String method, Object... args)
             throws IOException, TikaException {
-        List<ForkResource> r = new ArrayList<ForkResource>(resources);
+        List<ForkResource> r = new ArrayList<>(resources);
         output.writeByte(ForkServer.CALL);
         output.writeUTF(method);
-        for (int i = 0; i < args.length; i++) {
-            sendObject(args[i], r);
+        for (Object arg : args) {
+            sendObject(arg, r);
         }
         return waitForResponse(r);
     }
@@ -175,10 +169,7 @@
         if (process != null) {
             process.destroy();
         }
-        if (jar != null) {
-            jar.delete();
-        }
+    }
-    }
 
     private Throwable waitForResponse(List<ForkResource> resources)
             throws IOException {
@@ -233,21 +224,26 @@
      * server process. Remember to remove the file when no longer used.
      *
      * @return the created jar file
-     * @throws IOException if the bootstrap archive could not be created
+     * @throws RuntimeException if the bootstrap archive could not be created
      */
-    private static File createBootstrapJar() throws IOException {
-        File file = File.createTempFile("apache-tika-fork-", ".jar");
-        boolean ok = false;
+    private static Path createBootstrapJar() {
         try {
-            fillBootstrapJar(file);
-            ok = true;
-        } finally {
-            if (!ok) {
-                file.delete();
+            final Path file = Files.createTempFile("apache-tika-fork-", ".jar");
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                public void run() {
+                    try {
+                        Files.delete(file);
+                    } catch (IOException e) {
+                        throw new RuntimeException("cannot delete ForkClient bootstrap jar", e);
-            }
-        }
+                    }
+                }
+            });
+            fillBootstrapJar(file);
-        return file;
+            return file;
+        } catch (IOException e) {
+            throw new RuntimeException("cannot create ForkClient bootstrap jar", e);
-    }
+        }
+    }
 
     /**
      * Fills in the jar file used to bootstrap the forked server process.
@@ -257,9 +253,9 @@
      * @param file file to hold the bootstrap archive
      * @throws IOException if the bootstrap archive could not be created
      */
-    private static void fillBootstrapJar(File file) throws IOException {
+    private static void fillBootstrapJar(Path file) throws IOException {
         try (JarOutputStream jar =
-                new JarOutputStream(new FileOutputStream(file))) {
+                new JarOutputStream(Files.newOutputStream(file))) {
             String manifest =
                     "Main-Class: " + ForkServer.class.getName() + "\n";
             jar.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
Index: tika-core/src/test/java/org/apache/tika/fork/ForkParserTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- tika-core/src/test/java/org/apache/tika/fork/ForkParserTest.java	(revision 1703352)
+++ tika-core/src/test/java/org/apache/tika/fork/ForkParserTest.java	(revision )
@@ -16,13 +16,13 @@
  */
 package org.apache.tika.fork;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PipedInputStream;
 import java.io.PipedOutputStream;
 import java.util.concurrent.Semaphore;
 
+import org.apache.tika.io.NullInputStream;
 import org.apache.tika.metadata.Metadata;
 import org.apache.tika.parser.ParseContext;
 import org.apache.tika.sax.BodyContentHandler;
@@ -31,51 +31,44 @@
 import org.xml.sax.helpers.DefaultHandler;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 public class ForkParserTest {
 
+    private ForkParser newForkParser() {
+        return new ForkParser(ForkParserTest.class.getClassLoader(),
+                new ForkTestParser());
+    }
+
     @Test
     public void testHelloWorld() throws Exception {
-        ForkParser parser = new ForkParser(
-                ForkParserTest.class.getClassLoader(),
-                new ForkTestParser());
-        try {
+        try (ForkParser parser = newForkParser()) {
             Metadata metadata = new Metadata();
             ContentHandler output = new BodyContentHandler();
-            InputStream stream = new ByteArrayInputStream(new byte[0]);
+            InputStream stream = new NullInputStream(0);
             ParseContext context = new ParseContext();
             parser.parse(stream, output, metadata, context);
             assertEquals("Hello, World!", output.toString().trim());
             assertEquals("text/plain", metadata.get(Metadata.CONTENT_TYPE));
-        } finally {
-            parser.close();
         }
     }
 
     @Test
     public void testSerialParsing() throws Exception {
-        ForkParser parser = new ForkParser(
-                ForkParserTest.class.getClassLoader(),
-                new ForkTestParser());
-        try {
+        try (ForkParser parser = newForkParser()) {
             ParseContext context = new ParseContext();
             for (int i = 0; i < 10; i++) {
                 ContentHandler output = new BodyContentHandler();
-                InputStream stream = new ByteArrayInputStream(new byte[0]);
+                InputStream stream = new NullInputStream(0);
                 parser.parse(stream, output, new Metadata(), context);
                 assertEquals("Hello, World!", output.toString().trim());
             }
-        } finally {
-            parser.close();
         }
     }
 
     @Test
     public void testParallelParsing() throws Exception {
-        final ForkParser parser = new ForkParser(
-                ForkParserTest.class.getClassLoader(),
-                new ForkTestParser());
-        try {
+        try (ForkParser parser = newForkParser()) {
             final ParseContext context = new ParseContext();
 
             Thread[] threads = new Thread[10];
@@ -86,8 +79,7 @@
                 threads[i] = new Thread() {
                     public void run() {
                         try {
-                            InputStream stream =
-                                new ByteArrayInputStream(new byte[0]);
+                            InputStream stream = new NullInputStream(0);
                             parser.parse(stream, o, new Metadata(), context);
                         } catch (Exception e) {
                             e.printStackTrace();
@@ -101,17 +93,12 @@
                 threads[i].join();
                 assertEquals("Hello, World!", output[i].toString().trim());
             }
-        } finally {
-            parser.close();
         }
     }
 
     @Test
     public void testPoolSizeReached() throws Exception {
-        final ForkParser parser = new ForkParser(
-                ForkParserTest.class.getClassLoader(),
-                new ForkTestParser());
-        try {
+        try (ForkParser parser = newForkParser()) {
             final Semaphore barrier = new Semaphore(0);
 
             Thread[] threads = new Thread[parser.getPoolSize()];
@@ -147,8 +134,7 @@
                 public void run() {
                     try {
                         barrier.release();
-                        InputStream stream =
-                            new ByteArrayInputStream(new byte[0]);
+                        InputStream stream = new NullInputStream(0);
                         parser.parse(stream, o, new Metadata(), context);
                     } catch (Exception e) {
                         e.printStackTrace();
@@ -163,7 +149,7 @@
             barrier.acquire();
             Thread.sleep(1000);
 
-            assertEquals("", o.toString());
+            assertTrue(o.toString().isEmpty());
 
             for (int i = 0; i < threads.length; i++) {
                 pipes[i].close();
@@ -172,8 +158,6 @@
 
             blocked.join();
             assertEquals("Hello, World!", o.toString().trim());
-        } finally {
-            parser.close();
         }
     }
 
Index: tika-core/src/main/java/org/apache/tika/fork/ForkParser.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- tika-core/src/main/java/org/apache/tika/fork/ForkParser.java	(revision 1703352)
+++ tika-core/src/main/java/org/apache/tika/fork/ForkParser.java	(revision )
@@ -16,6 +16,7 @@
  */
 package org.apache.tika.fork;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -37,7 +38,7 @@
 import org.xml.sax.ContentHandler;
 import org.xml.sax.SAXException;
 
-public class ForkParser extends AbstractParser {
+public class ForkParser extends AbstractParser implements Closeable {
 
     /** Serial version UID */
     private static final long serialVersionUID = -4962742892274663950L;
@@ -54,8 +55,7 @@
 
     private int currentlyInUse = 0;
 
-    private final Queue<ForkClient> pool =
-        new LinkedList<ForkClient>();
+    private final Queue<ForkClient> pool = new LinkedList<>();
 
     /**
      * @param loader The ClassLoader to use 
@@ -132,14 +132,14 @@
      * @param java java command line
      */
     public void setJavaCommand(List<String> java) {
-        this.java = new ArrayList<String>(java);
+        this.java = new ArrayList<>(java);
     }
 
     /**
      * Sets the command used to start the forked server process.
      * The given command line is split on whitespace and the arguments
-2    * "-jar" and "/path/to/bootstrap.jar" are appended to it when starting
-2    * the process. The default setting is "java -Xmx32m".
+     * "-jar" and "/path/to/bootstrap.jar" are appended to it when starting
+     * the process. The default setting is "java -Xmx32m".
      *
      * @param java java command line
      * @deprecated since 1.8
