You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2021/09/19 16:16:39 UTC

[commons-io] branch master updated (d6d99a6 -> 19df5f9)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git.


    from d6d99a6  Clean ups.
     new 69e3b81  Method that allocates should release resources.
     new 19df5f9  Try to fix random build failures on GitHub.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/commons/io/input/Tailer.java   |  17 +-
 .../apache/commons/io/ThreadMonitorTestCase.java   |   3 +-
 .../org/apache/commons/io/input/TailerTest.java    | 456 +++++++++++----------
 3 files changed, 248 insertions(+), 228 deletions(-)

[commons-io] 02/02: Try to fix random build failures on GitHub.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 19df5f983929dc07af9d5ebabb571585dd214c0b
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Sep 19 12:16:35 2021 -0400

    Try to fix random build failures on GitHub.
---
 src/test/java/org/apache/commons/io/ThreadMonitorTestCase.java | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/test/java/org/apache/commons/io/ThreadMonitorTestCase.java b/src/test/java/org/apache/commons/io/ThreadMonitorTestCase.java
index 3be1ba2..4d49645 100644
--- a/src/test/java/org/apache/commons/io/ThreadMonitorTestCase.java
+++ b/src/test/java/org/apache/commons/io/ThreadMonitorTestCase.java
@@ -48,7 +48,6 @@ public class ThreadMonitorTestCase {
      */
     @Test
     public void testNoTimeout() {
-
         // timeout = -1
         try {
             final Thread monitor = ThreadMonitor.start(Duration.ofMillis(-1));
@@ -77,7 +76,7 @@ public class ThreadMonitorTestCase {
     public void testTimeout() {
         try {
             final Thread monitor = ThreadMonitor.start(Duration.ofMillis(100));
-            TestUtils.sleep(200);
+            TestUtils.sleep(400);
             ThreadMonitor.stop(monitor);
             fail("Expected InterruptedException");
         } catch (final InterruptedException e) {

[commons-io] 01/02: Method that allocates should release resources.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-io.git

commit 69e3b819a154793128ec7c0336d33623f6cc8a21
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Sep 19 12:15:50 2021 -0400

    Method that allocates should release resources.
    
    Use try-with-resources with Tailer as an AutoCloseable.
    All tests now manage its own resource.
---
 .../java/org/apache/commons/io/input/Tailer.java   |  17 +-
 .../org/apache/commons/io/input/TailerTest.java    | 456 +++++++++++----------
 2 files changed, 247 insertions(+), 226 deletions(-)

diff --git a/src/main/java/org/apache/commons/io/input/Tailer.java b/src/main/java/org/apache/commons/io/input/Tailer.java
index c881f32..349f848 100644
--- a/src/main/java/org/apache/commons/io/input/Tailer.java
+++ b/src/main/java/org/apache/commons/io/input/Tailer.java
@@ -155,7 +155,7 @@ import org.apache.commons.io.file.attribute.FileTimes;
  *        alternative libraries such as jCIFS or <a href="https://commons.apache.org/proper/commons-vfs/">Apache Commons
  *        VFS</a>.
  */
-public class Tailer implements Runnable {
+public class Tailer implements Runnable, AutoCloseable {
 
     /**
      * Builds a {@link Tailer} with default values.
@@ -769,6 +769,14 @@ public class Tailer implements Runnable {
     }
 
     /**
+     * Requests the tailer to complete its current loop and return.
+     */
+    @Override
+    public void close() {
+        this.run = false;
+    }
+
+    /**
      * Gets the delay in milliseconds.
      *
      * @return the delay in milliseconds.
@@ -963,14 +971,17 @@ public class Tailer implements Runnable {
             } catch (final IOException e) {
                 listener.handle(e);
             }
-            stop();
+            close();
         }
     }
 
     /**
      * Requests the tailer to complete its current loop and return.
+     *
+     * @deprecated Use {@link #close()}.
      */
+    @Deprecated
     public void stop() {
-        this.run = false;
+        close();
     }
 }
diff --git a/src/test/java/org/apache/commons/io/input/TailerTest.java b/src/test/java/org/apache/commons/io/input/TailerTest.java
index 97f8ea3..6ce918e 100644
--- a/src/test/java/org/apache/commons/io/input/TailerTest.java
+++ b/src/test/java/org/apache/commons/io/input/TailerTest.java
@@ -45,7 +45,6 @@ import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.TestResources;
@@ -54,6 +53,8 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
 
+import com.google.common.collect.Lists;
+
 /**
  * Test for {@link Tailer}.
  */
@@ -143,7 +144,7 @@ public class TailerTest {
             latch = new CountDownLatch(expectedLines);
         }
 
-        public boolean awaitExpectedLines(long timeout, TimeUnit timeUnit) throws InterruptedException {
+        public boolean awaitExpectedLines(final long timeout, final TimeUnit timeUnit) throws InterruptedException {
             return latch.await(timeout, timeUnit);
         }
 
@@ -190,8 +191,6 @@ public class TailerTest {
     @TempDir
     public static File temporaryFolder;
 
-    private Tailer tailer;
-
     protected void createFile(final File file, final long size) throws IOException {
         assertTrue(file.getParentFile().exists(), () -> "Cannot create file " + file + " as the parent directory does not exist");
         try (final BufferedOutputStream output = new BufferedOutputStream(Files.newOutputStream(file.toPath()))) {
@@ -215,13 +214,6 @@ public class TailerTest {
         }
     }
 
-    @AfterEach
-    public void tearDown() {
-        if (tailer != null) {
-            tailer.stop();
-        }
-    }
-
     @Test
     @SuppressWarnings("squid:S2699") // Suppress "Add at least one assertion to this test case"
     public void testBufferBreak() throws Exception {
@@ -232,17 +224,17 @@ public class TailerTest {
         writeString(file, "SBTOURIST\n");
 
         final TestTailerListener listener = new TestTailerListener();
-        tailer = new Tailer(file, listener, delay, false, 1);
+        try (Tailer tailer = new Tailer(file, listener, delay, false, 1)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        final Thread thread = new Thread(tailer);
-        thread.start();
+            List<String> lines = listener.getLines();
+            while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) {
+                lines = listener.getLines();
+            }
 
-        List<String> lines = listener.getLines();
-        while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) {
-            lines = listener.getLines();
+            listener.clear();
         }
-
-        listener.clear();
     }
 
     @Test
@@ -250,9 +242,10 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer.Builder(new NonStandardTailable(file), listener).build();
-        assertTrue(tailer.getTailable() instanceof NonStandardTailable);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer.Builder(new NonStandardTailable(file), listener).build()) {
+            assertTrue(tailer.getTailable() instanceof NonStandardTailable);
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -260,8 +253,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -269,8 +263,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, false);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, false)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -278,8 +273,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -287,8 +283,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -296,8 +293,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-buffersize.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -305,8 +303,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -314,8 +313,9 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-create-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = Tailer.create(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE);
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = Tailer.create(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) {
+            validateTailer(listener, tailer, file);
+        }
     }
 
     /*
@@ -329,19 +329,20 @@ public class TailerTest {
         // Use a long delay to try to make sure the test thread calls interrupt() while the tailer thread is sleeping.
         final int delay = 1000;
         final int idle = 50; // allow time for thread to work
-        tailer = new Tailer(file, listener, delay, false, IOUtils.DEFAULT_BUFFER_SIZE);
-        final Thread thread = new Thread(tailer);
-        thread.setDaemon(true);
-        thread.start();
-        TestUtils.sleep(idle);
-        thread.interrupt();
-        TestUtils.sleep(delay + idle);
-        assertNotNull(listener.exception, "Missing InterruptedException");
-        assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception);
-        assertEquals(1, listener.initialized, "Expected init to be called");
-        assertTrue(listener.notFound > 0, "fileNotFound should be called");
-        assertEquals(0, listener.rotated, "fileRotated should be not be called");
-        assertEquals(0, listener.reachedEndOfFile, "end of file never reached");
+        try (Tailer tailer = new Tailer(file, listener, delay, false, IOUtils.DEFAULT_BUFFER_SIZE)) {
+            final Thread thread = new Thread(tailer);
+            thread.setDaemon(true);
+            thread.start();
+            TestUtils.sleep(idle);
+            thread.interrupt();
+            TestUtils.sleep(delay + idle);
+            assertNotNull(listener.exception, "Missing InterruptedException");
+            assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception);
+            assertEquals(1, listener.initialized, "Expected init to be called");
+            assertTrue(listener.notFound > 0, "fileNotFound should be called");
+            assertEquals(0, listener.rotated, "fileRotated should be not be called");
+            assertEquals(0, listener.reachedEndOfFile, "end of file never reached");
+        }
     }
 
     @Test
@@ -351,20 +352,21 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-testio334.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener();
-        tailer = new Tailer(file, listener, delayMillis, false);
-        final Thread thread = new Thread(tailer);
-        thread.start();
+        try (Tailer tailer = new Tailer(file, listener, delayMillis, false)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        // Write some lines to the file
-        writeString(file, "CRLF\r\n", "LF\n", "CR\r", "CRCR\r\r", "trail");
-        final long testDelayMillis = delayMillis * 10;
-        TestUtils.sleep(testDelayMillis);
-        final List<String> lines = listener.getLines();
-        assertEquals(4, lines.size(), "line count");
-        assertEquals("CRLF", lines.get(0), "line 1");
-        assertEquals("LF", lines.get(1), "line 2");
-        assertEquals("CR", lines.get(2), "line 3");
-        assertEquals("CRCR\r", lines.get(3), "line 4");
+            // Write some lines to the file
+            writeString(file, "CRLF\r\n", "LF\n", "CR\r", "CRCR\r\r", "trail");
+            final long testDelayMillis = delayMillis * 10;
+            TestUtils.sleep(testDelayMillis);
+            final List<String> lines = listener.getLines();
+            assertEquals(4, lines.size(), "line count");
+            assertEquals("CRLF", lines.get(0), "line 1");
+            assertEquals("LF", lines.get(1), "line 2");
+            assertEquals("CR", lines.get(2), "line 3");
+            assertEquals("CRCR\r", lines.get(3), "line 4");
+        }
     }
 
     @Test
@@ -382,20 +384,21 @@ public class TailerTest {
         }
 
         final TestTailerListener listener = new TestTailerListener();
-        tailer = new Tailer(file, listener, delay, false);
+        try (Tailer tailer = new Tailer(file, listener, delay, false)) {
 
-        // final long start = System.currentTimeMillis();
+            // final long start = System.currentTimeMillis();
 
-        final Thread thread = new Thread(tailer);
-        thread.start();
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        List<String> lines = listener.getLines();
-        while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) {
-            lines = listener.getLines();
-        }
-        // System.out.println("Elapsed: " + (System.currentTimeMillis() - start));
+            List<String> lines = listener.getLines();
+            while (lines.isEmpty() || !lines.get(lines.size() - 1).equals("SBTOURIST")) {
+                lines = listener.getLines();
+            }
+            // System.out.println("Elapsed: " + (System.currentTimeMillis() - start));
 
-        listener.clear();
+            listener.clear();
+        }
     }
 
     @Test
@@ -410,30 +413,31 @@ public class TailerTest {
         final boolean isWindows = osname.startsWith("Windows");
         // Need to use UTF-8 to read & write the file otherwise it can be corrupted (depending on the default charset)
         final Charset charsetUTF8 = StandardCharsets.UTF_8;
-        tailer = new Tailer(file, charsetUTF8, listener, delay, false, isWindows, IOUtils.DEFAULT_BUFFER_SIZE);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-
-        try (Writer out = new OutputStreamWriter(Files.newOutputStream(file.toPath()), charsetUTF8);
-            BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(origin.toPath()), charsetUTF8))) {
-            final List<String> lines = new ArrayList<>();
-            String line;
-            while ((line = reader.readLine()) != null) {
-                out.write(line);
-                out.write("\n");
-                lines.add(line);
-            }
-            out.close(); // ensure data is written
-
-            final long testDelayMillis = delay * 10;
-            TestUtils.sleep(testDelayMillis);
-            final List<String> tailerlines = listener.getLines();
-            assertEquals(lines.size(), tailerlines.size(), "line count");
-            for (int i = 0, len = lines.size(); i < len; i++) {
-                final String expected = lines.get(i);
-                final String actual = tailerlines.get(i);
-                if (!expected.equals(actual)) {
-                    fail("Line: " + i + "\nExp: (" + expected.length() + ") " + expected + "\nAct: (" + actual.length() + ") " + actual);
+        try (Tailer tailer = new Tailer(file, charsetUTF8, listener, delay, false, isWindows, IOUtils.DEFAULT_BUFFER_SIZE)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+
+            try (Writer out = new OutputStreamWriter(Files.newOutputStream(file.toPath()), charsetUTF8);
+                BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(origin.toPath()), charsetUTF8))) {
+                final List<String> lines = new ArrayList<>();
+                String line;
+                while ((line = reader.readLine()) != null) {
+                    out.write(line);
+                    out.write("\n");
+                    lines.add(line);
+                }
+                out.close(); // ensure data is written
+
+                final long testDelayMillis = delay * 10;
+                TestUtils.sleep(testDelayMillis);
+                final List<String> tailerlines = listener.getLines();
+                assertEquals(lines.size(), tailerlines.size(), "line count");
+                for (int i = 0, len = lines.size(); i < len; i++) {
+                    final String expected = lines.get(i);
+                    final String actual = tailerlines.get(i);
+                    if (!expected.equals(actual)) {
+                        fail("Line: " + i + "\nExp: (" + expected.length() + ") " + expected + "\nAct: (" + actual.length() + ") " + actual);
+                    }
                 }
             }
         }
@@ -444,10 +448,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -455,10 +460,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -466,10 +472,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -477,10 +484,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-buffersize.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, TEST_BUFFER_SIZE)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -488,10 +496,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, false);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, false)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -499,10 +508,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen-and-buffersize.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -510,10 +520,11 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer-simple-constructor-with-delay-and-from-start-with-reopen-and-buffersize-and-charset.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener(1);
-        final Tailer tailer = new Tailer(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE);
-        final Thread thread = new Thread(tailer);
-        thread.start();
-        validateTailer(listener, tailer, file);
+        try (final Tailer tailer = new Tailer(file, StandardCharsets.UTF_8, listener, TEST_DELAY_MILLIS, false, true, TEST_BUFFER_SIZE)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
+            validateTailer(listener, tailer, file);
+        }
     }
 
     @Test
@@ -523,9 +534,9 @@ public class TailerTest {
         final TestTailerListener listener = new TestTailerListener();
         final int delay = 100;
         final int idle = 50; // allow time for thread to work
-        tailer = Tailer.create(file, listener, delay, false);
-        TestUtils.sleep(idle);
-        tailer.stop();
+        try (Tailer tailer = Tailer.create(file, listener, delay, false)) {
+            TestUtils.sleep(idle);
+        }
         TestUtils.sleep(delay + idle);
         assertNull(listener.exception, "Should not generate Exception");
         assertEquals(1, listener.initialized, "Expected init to be called");
@@ -541,11 +552,11 @@ public class TailerTest {
         final TestTailerListener listener = new TestTailerListener();
         final int delay = 100;
         final int idle = 50; // allow time for thread to work
-        tailer = new Tailer(file, listener, delay, false);
-        final Executor exec = new ScheduledThreadPoolExecutor(1);
-        exec.execute(tailer);
-        TestUtils.sleep(idle);
-        tailer.stop();
+        try (Tailer tailer = new Tailer(file, listener, delay, false)) {
+            final Executor exec = new ScheduledThreadPoolExecutor(1);
+            exec.execute(tailer);
+            TestUtils.sleep(idle);
+        }
         TestUtils.sleep(delay + idle);
         assertNull(listener.exception, "Should not generate Exception");
         assertEquals(1, listener.initialized, "Expected init to be called");
@@ -564,61 +575,62 @@ public class TailerTest {
         final TestTailerListener listener = new TestTailerListener();
         final String osname = System.getProperty("os.name");
         final boolean isWindows = osname.startsWith("Windows");
-        tailer = new Tailer(file, listener, delayMillis, false, isWindows);
-        final Thread thread = new Thread(tailer);
-        thread.start();
+        try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        // Write some lines to the file
-        write(file, "Line one", "Line two");
-        final long testDelayMillis = delayMillis * 10;
-        TestUtils.sleep(testDelayMillis);
-        List<String> lines = listener.getLines();
-        assertEquals(2, lines.size(), "1 line count");
-        assertEquals("Line one", lines.get(0), "1 line 1");
-        assertEquals("Line two", lines.get(1), "1 line 2");
-        listener.clear();
-
-        // Write another line to the file
-        write(file, "Line three");
-        TestUtils.sleep(testDelayMillis);
-        lines = listener.getLines();
-        assertEquals(1, lines.size(), "2 line count");
-        assertEquals("Line three", lines.get(0), "2 line 3");
-        listener.clear();
-
-        // Check file does actually have all the lines
-        lines = FileUtils.readLines(file, "UTF-8");
-        assertEquals(3, lines.size(), "3 line count");
-        assertEquals("Line one", lines.get(0), "3 line 1");
-        assertEquals("Line two", lines.get(1), "3 line 2");
-        assertEquals("Line three", lines.get(2), "3 line 3");
-
-        // Delete & re-create
-        file.delete();
-        assertFalse(file.exists(), "File should not exist");
-        createFile(file, 0);
-        assertTrue(file.exists(), "File should now exist");
-        TestUtils.sleep(testDelayMillis);
-
-        // Write another line
-        write(file, "Line four");
-        TestUtils.sleep(testDelayMillis);
-        lines = listener.getLines();
-        assertEquals(1, lines.size(), "4 line count");
-        assertEquals("Line four", lines.get(0), "4 line 3");
-        listener.clear();
-
-        // Stop
-        thread.interrupt();
-        TestUtils.sleep(testDelayMillis * 4);
-        write(file, "Line five");
-        assertEquals(0, listener.getLines().size(), "4 line count");
-        assertNotNull(listener.exception, "Missing InterruptedException");
-        assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception);
-        assertEquals(1, listener.initialized, "Expected init to be called");
-        // assertEquals(0 , listener.notFound, "fileNotFound should not be called"); // there is a window when it might be
-        // called
-        assertEquals(1, listener.rotated, "fileRotated should be be called");
+            // Write some lines to the file
+            write(file, "Line one", "Line two");
+            final long testDelayMillis = delayMillis * 10;
+            TestUtils.sleep(testDelayMillis);
+            List<String> lines = listener.getLines();
+            assertEquals(2, lines.size(), "1 line count");
+            assertEquals("Line one", lines.get(0), "1 line 1");
+            assertEquals("Line two", lines.get(1), "1 line 2");
+            listener.clear();
+
+            // Write another line to the file
+            write(file, "Line three");
+            TestUtils.sleep(testDelayMillis);
+            lines = listener.getLines();
+            assertEquals(1, lines.size(), "2 line count");
+            assertEquals("Line three", lines.get(0), "2 line 3");
+            listener.clear();
+
+            // Check file does actually have all the lines
+            lines = FileUtils.readLines(file, "UTF-8");
+            assertEquals(3, lines.size(), "3 line count");
+            assertEquals("Line one", lines.get(0), "3 line 1");
+            assertEquals("Line two", lines.get(1), "3 line 2");
+            assertEquals("Line three", lines.get(2), "3 line 3");
+
+            // Delete & re-create
+            file.delete();
+            assertFalse(file.exists(), "File should not exist");
+            createFile(file, 0);
+            assertTrue(file.exists(), "File should now exist");
+            TestUtils.sleep(testDelayMillis);
+
+            // Write another line
+            write(file, "Line four");
+            TestUtils.sleep(testDelayMillis);
+            lines = listener.getLines();
+            assertEquals(1, lines.size(), "4 line count");
+            assertEquals("Line four", lines.get(0), "4 line 3");
+            listener.clear();
+
+            // Stop
+            thread.interrupt();
+            TestUtils.sleep(testDelayMillis * 4);
+            write(file, "Line five");
+            assertEquals(0, listener.getLines().size(), "4 line count");
+            assertNotNull(listener.exception, "Missing InterruptedException");
+            assertTrue(listener.exception instanceof InterruptedException, "Unexpected Exception: " + listener.exception);
+            assertEquals(1, listener.initialized, "Expected init to be called");
+            // assertEquals(0 , listener.notFound, "fileNotFound should not be called"); // there is a window when it might be
+            // called
+            assertEquals(1, listener.rotated, "fileRotated should be be called");
+        }
     }
 
     @Test
@@ -631,24 +643,25 @@ public class TailerTest {
         final TestTailerListener listener = new TestTailerListener();
         final String osname = System.getProperty("os.name");
         final boolean isWindows = osname.startsWith("Windows");
-        tailer = new Tailer(file, listener, delayMillis, false, isWindows);
-        final Thread thread = new Thread(tailer);
-        thread.start();
+        try (Tailer tailer = new Tailer(file, listener, delayMillis, false, isWindows)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        // write a few lines
-        write(file, "line1", "line2", "line3");
-        TestUtils.sleep(testDelayMillis);
+            // write a few lines
+            write(file, "line1", "line2", "line3");
+            TestUtils.sleep(testDelayMillis);
 
-        // write a few lines
-        write(file, "line4", "line5", "line6");
-        TestUtils.sleep(testDelayMillis);
+            // write a few lines
+            write(file, "line4", "line5", "line6");
+            TestUtils.sleep(testDelayMillis);
 
-        // write a few lines
-        write(file, "line7", "line8", "line9");
-        TestUtils.sleep(testDelayMillis);
+            // write a few lines
+            write(file, "line7", "line8", "line9");
+            TestUtils.sleep(testDelayMillis);
 
-        // May be > 3 times due to underlying OS behavior wrt streams
-        assertTrue(listener.reachedEndOfFile >= 3, "end of file reached at least 3 times");
+            // May be > 3 times due to underlying OS behavior wrt streams
+            assertTrue(listener.reachedEndOfFile >= 3, "end of file reached at least 3 times");
+        }
     }
 
     @Test
@@ -658,37 +671,34 @@ public class TailerTest {
         final File file = new File(temporaryFolder, "tailer2-test.txt");
         createFile(file, 0);
         final TestTailerListener listener = new TestTailerListener();
-        tailer = new Tailer(file, listener, delay, false);
-        final Thread thread = new Thread(tailer);
-        thread.start();
+        try (Tailer tailer = new Tailer(file, listener, delay, false)) {
+            final Thread thread = new Thread(tailer);
+            thread.start();
 
-        // Write some lines to the file
-        writeString(file, "Line");
+            // Write some lines to the file
+            writeString(file, "Line");
 
-        TestUtils.sleep(delay * 2);
-        List<String> lines = listener.getLines();
-        assertEquals(0, lines.size(), "1 line count");
+            TestUtils.sleep(delay * 2);
+            List<String> lines = listener.getLines();
+            assertEquals(0, lines.size(), "1 line count");
 
-        writeString(file, " one\n");
-        TestUtils.sleep(delay * 2);
-        lines = listener.getLines();
+            writeString(file, " one\n");
+            TestUtils.sleep(delay * 2);
+            lines = listener.getLines();
 
-        assertEquals(1, lines.size(), "1 line count");
-        assertEquals("Line one", lines.get(0), "1 line 1");
+            assertEquals(1, lines.size(), "1 line count");
+            assertEquals("Line one", lines.get(0), "1 line 1");
 
-        listener.clear();
+            listener.clear();
+        }
     }
 
     private void validateTailer(final TestTailerListener listener, final Tailer tailer, final File file) throws Exception {
-        try {
-            write(file, "foo");
-            final int timeout = 30;
-            final TimeUnit timeoutUnit = TimeUnit.SECONDS;
-            assertTrue(listener.awaitExpectedLines(timeout, timeoutUnit), () -> String.format("await timed out after %s %s", timeout, timeoutUnit));
-            assertEquals(listener.getLines(), Lists.newArrayList("foo"), "lines");
-        } finally {
-            tailer.stop();
-        }
+        write(file, "foo");
+        final int timeout = 30;
+        final TimeUnit timeoutUnit = TimeUnit.SECONDS;
+        assertTrue(listener.awaitExpectedLines(timeout, timeoutUnit), () -> String.format("await timed out after %s %s", timeout, timeoutUnit));
+        assertEquals(listener.getLines(), Lists.newArrayList("foo"), "lines");
     }
 
     /** Appends lines to a file */