0

I have a code that looks like this (I put everything into a single method just for shorter code).

public static void main(String[] args) {

    @lombok.Data
    class Data {
        Data previous;
        String text;

        public Data(Data data) {
            this.text = data.text;
        }

        public Data(String text) {
            this.text = text;
        }
    }

    class PlainThread implements Runnable {
        private Data data;

        public PlainThread(Data data) {
            this.data = data;
        }

        @Override
        public void run() {
            int i = 0;
            while (i != 5) {
                // application stops but no notification of exception
                System.out.println(data.previous.text);

                ThreadUtils.delaySeconds(1);
                i++;
            }
        }
    }

    System.out.println("Starting...");
    Data data = new Data("Simple text");
    // application fails there
    // System.out.println(data.previous.text);

    PlainThread thread = new PlainThread(new Data("Simple text"));
    ExecutorService executorService = Executors.newFixedThreadPool(2);
    executorService.submit(thread);
    executorService.shutdown();
}

Basically I create object Data that contains the reference to another Data object which is null by default. I put this object in the thread that supposed to get the field text of this another object. As I did not set previous when I instantiated the object

Data data = new Data("Simple text");

I put the thread into the ExecutorService. I expected to receive Null Pointer Exception in console and application failure inside this thread loop

while (i != 5) {
    // application stops but no notification of exception
    System.out.println(data.previous.text);

    ThreadUtils.delaySeconds(1);
    i++;
}

But I don't get the notification (or stack trace in console) that exception occurs.

If I wrap System.out.println into try-catch block inside the while loop

try {
    // application stops but no notification of exception
    System.out.println(data.previous.text);
} catch (Exception exc) {
    System.out.println(exc);
}

It prints out the exception java.lang.NullPointerException.

Why it's happening? Why it doesn't show exception in console like

Exception in thread "main" java.lang.NullPointerException
    at com.xxx.Main.main(Main.java:83)

Edit: The question is not the duplicate to How to catch an Exception from a thread as I don't ask how to catch the exception but ask why it doesn't notify about the exception.

lapots
  • 12,553
  • 32
  • 121
  • 242
  • I don't agree with duplication, because I am not asking how to catch the exception, but asking why it doesn't print stack trace when exception occurred inside the thread. – lapots Jun 15 '19 at 10:01
  • As you can find in https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/ExecutorService.html Submit returns a future, so in your case, as you are not doing anything with it, the program will continue until the main threads and it's childs are closed – David Barda Jun 15 '19 at 10:02
  • @DavidBarda so basically in order to receive the exception I need to use `reactive` style and receive it from `get`?. hm, but why it doesn't display stacktrace without manual catch? – lapots Jun 15 '19 at 10:04
  • I don't understand what reactive style means in this case, but if the child thread is not getting to the point of throwing the exception and the main thread is closed, so no exception will take place – David Barda Jun 15 '19 at 10:05
  • but the thing is that it throws the exception - manual `catch` block displays that exception occurred. But no notification by default. Like, in my application I didn't even know that exception took place at all, untill entered debug mode. – lapots Jun 15 '19 at 10:08
  • I thought you were running the catch in the main thread for some reason, anyway from what I understand now, than it's really a duplication, as there is not exception handler and nothings is happening with this exception(e.g try to remove the print of the exception, nothing will happen in this case too) – David Barda Jun 15 '19 at 10:19
  • In `main` thread it will print stack trace. In a `plainThread` it won't do that. And `exception handler` is no use as I use `Runnable` and not `thread` object. – lapots Jun 15 '19 at 10:27
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/194982/discussion-between-david-barda-and-lapots). – David Barda Jun 15 '19 at 10:27
  • So finally the answer is regarding the task which is being created by the executor service, java.util.concurrent.FutureTask#run is keeping the exception in a field, and set the state of the task to Exceptional, in that case unless you call some methods(as .get) nothing will happened with this exception in the main thread – David Barda Jun 15 '19 at 10:41

0 Answers0