file writing programm randomly exits without errors

currently i'm trying to write to a txt-file with Java's Files-Class. This task should be done every 5 seconds and is scheduled by an ScheduledExecutorService. For some time it's doing it's job propperly but after a random time my program exits without any warnings, errors or so. I have tried to reproduce this but it seems to occur very random. I've also tried to use a PrintWriter but that lead randomly to the same behaviour.

Thanks in advance!!!

Here is my code:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class FileWritingClass
{
    public static void main(String[] args) throws IOException
    {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        scheduler.scheduleAtFixedRate(
            new Runnable() {
                long i;
                String str = "";
                Path path = Paths.get("TestFile.txt");

                @Override
                public void run() {

                    str = LocalTime.now().toString() + ": still alive after " + i + " times.";
                    i++;

                    try
                    {   
                        System.out.println(str);
                        Files.write(path, (str + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            },
            500 /* Startdelay */,
            5000 /* period */,
            TimeUnit.MILLISECONDS );        
    }
}

1 answer

  • answered 2019-10-14 11:40 Thomas Timbul

    The Executor is swallowing Exceptions other than IOException. Catch Throwable instead of just IOException.

    The Executor fails when it encounters some Exception other than IOException. The VM is still alive, but the Executor has failed.

    Here's some code to try:

                        try
                        {   
                            System.out.println(str);
                            Files.write(path, (str + System.lineSeparator()).getBytes(), StandardOpenOption.APPEND);
                            if(new Random().nextBoolean()) {
                                System.out.println("Here we go.");
                                throw new RuntimeException("Uncaught");
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } catch(Throwable t) {
                            t.printStackTrace();
                            System.out.println("The show must go on...");
                        }
    

    Note how I give a 50/50 chance to throw an uncaught exception after the write (just for quick failure). If you remove the second catch, it will just stop printing. With the catch, the output becomes:

    12:46:00.780250700: still alive after 0 times.
    12:46:05.706355500: still alive after 1 times.
    Here we go.
    java.lang.RuntimeException:
    Uncaught at
    KeepaTokenRecorder$FileWritingClass$1.run(KeepaTokenRecorder.java:89)
        at [...]
    The show must go on...
    12:46:15.705899200: still alive after 3 times.