Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Blowing the stack on purpose with CompletableFuture yielded no stack overflow?

I am trying to see the behavior on purposefully causing a stack overflow with CompletableFuture but instead found out, it resulted in success and my recursive loop just stopped and exited and junit test passed. This is really not the behavior I would want. I would want a fail fast behavior so I know to fix my code.

@Test
public void testBlowTheStack() throws InterruptedException {
    recurse(0);

    System.out.println("done");
    Thread.sleep(5000);
}


private void recurse(int counter) {
    CompletableFuture<Integer> future = writeData(counter);
    future.thenAccept(p -> recurse(p+1));       
}

private CompletableFuture<Integer> writeData(int counter) {
    System.out.println("counter="+counter);
    if(counter == 1455) {
        System.out.println("mark");
    }

    CompletableFuture<Integer> future = new CompletableFuture<Integer>();
    future.complete(counter);
    return future;
}

I tried to debug in eclipse around count 1455 but eclipse freezes and can't load the stack trace so I could not find the reason behind this behavior.

So my questions are simple

  1. Is my code somehow incorrect?
  2. how is the CompletableFuture exiting successfully (or perhaps it isn't in which case how is my junit test case passing).

Maybe OS matters...I am on a mac. I previously had my own home grown promises and those successfully blow the stack.

like image 471
Dean Hiller Avatar asked Sep 13 '26 20:09

Dean Hiller


1 Answers

thenAccept takes a Consumer and returns a CompletableFuture<Void>. If the consumer returns normally without exception, the void future is completed with null. If the consumer throws an exception the future is completed exceptionally with that exception.

If you want to catch the StackOverflowException you need to get it from the returned future. There are many ways to do that. For example:

future.thenAccept(p -> recurse(p+1)).join();

or

future.thenAccept(p -> recurse(p+1))
      .exceptionally(e -> {
          e.printStackTrace();
          return null;
      });
like image 136
John Kugelman Avatar answered Sep 15 '26 08:09

John Kugelman