Skip to content

Commit 0366900

Browse files
committed
Check for null context when trying to find an exception mapper
If application context refresh fails, SpringApplication will have a null context. Previously, this would result in an NPE when looking for an ExitCodeExceptionMapper. This commit updates SpringApplication to gracefully handle the context being null when looking for an ExitCodeExceptionMapper. Closes gh-4803
1 parent ea5195c commit 0366900

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

spring-boot/src/main/java/org/springframework/boot/SpringApplication.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,9 @@ private int getExitCodeFromException(ConfigurableApplicationContext context,
881881

882882
private int getExitCodeFromMappedException(ConfigurableApplicationContext context,
883883
Throwable exception) {
884+
if (context == null) {
885+
return 0;
886+
}
884887
ExitCodeGenerators generators = new ExitCodeGenerators();
885888
Collection<ExitCodeExceptionMapper> beans = context
886889
.getBeansOfType(ExitCodeExceptionMapper.class).values();

spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import java.util.Set;
2525
import java.util.concurrent.atomic.AtomicReference;
2626

27+
import javax.annotation.PostConstruct;
28+
2729
import org.junit.After;
2830
import org.junit.Before;
2931
import org.junit.Rule;
@@ -74,6 +76,7 @@
7476
import static org.hamcrest.Matchers.instanceOf;
7577
import static org.hamcrest.Matchers.is;
7678
import static org.hamcrest.Matchers.isA;
79+
import static org.hamcrest.Matchers.not;
7780
import static org.hamcrest.Matchers.sameInstance;
7881
import static org.hamcrest.Matchers.startsWith;
7982
import static org.junit.Assert.assertArrayEquals;
@@ -83,6 +86,7 @@
8386
import static org.junit.Assert.assertThat;
8487
import static org.junit.Assert.assertTrue;
8588
import static org.junit.Assert.fail;
89+
import static org.mockito.Matchers.any;
8690
import static org.mockito.Matchers.anyObject;
8791
import static org.mockito.Mockito.atLeastOnce;
8892
import static org.mockito.Mockito.mock;
@@ -615,6 +619,31 @@ SpringBootExceptionHandler getSpringBootExceptionHandler() {
615619
assertThat(listener.getExitCode(), equalTo(11));
616620
}
617621

622+
@Test
623+
public void exceptionFromRefreshIsHandledGracefully() throws Exception {
624+
final SpringBootExceptionHandler handler = mock(SpringBootExceptionHandler.class);
625+
SpringApplication application = new SpringApplication(
626+
RefreshFailureConfig.class) {
627+
628+
@Override
629+
SpringBootExceptionHandler getSpringBootExceptionHandler() {
630+
return handler;
631+
}
632+
633+
};
634+
ExitCodeListener listener = new ExitCodeListener();
635+
application.addListeners(listener);
636+
application.setWebEnvironment(false);
637+
try {
638+
application.run();
639+
fail("Did not throw");
640+
}
641+
catch (RuntimeException ex) {
642+
}
643+
verify(handler).registerLoggedException(any(RefreshFailureException.class));
644+
assertThat(this.output.toString(), not(containsString("NullPointerException")));
645+
}
646+
618647
@Test
619648
public void defaultCommandLineArgs() throws Exception {
620649
SpringApplication application = new SpringApplication(ExampleConfig.class);
@@ -966,6 +995,15 @@ public int getExitCode(Throwable exception) {
966995

967996
}
968997

998+
@Configuration
999+
static class RefreshFailureConfig {
1000+
1001+
@PostConstruct
1002+
public void fail() {
1003+
throw new RefreshFailureException();
1004+
}
1005+
}
1006+
9691007
static class ExitStatusException extends RuntimeException
9701008
implements ExitCodeGenerator {
9711009

@@ -976,6 +1014,10 @@ public int getExitCode() {
9761014

9771015
}
9781016

1017+
static class RefreshFailureException extends RuntimeException {
1018+
1019+
}
1020+
9791021
static class AbstractTestRunner implements ApplicationContextAware, Ordered {
9801022

9811023
private final String[] expectedBefore;

0 commit comments

Comments
 (0)