From 5b97981c87e35876177ee5513fbaedd16b9db9bf Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 20 Jun 2016 18:13:43 -0700 Subject: [PATCH] Polish --- .../endpoint/mvc/HalBrowserMvcEndpoint.java | 6 +- ...ManagementContextPathIntegrationTests.java | 3 +- ...ointServerContextPathIntegrationTests.java | 4 +- .../IntegrationAutoConfiguration.java | 6 +- .../restart/SilentExitExceptionHandler.java | 69 +++++++++---------- .../SilentExitExceptionHandlerTests.java | 3 +- .../main/asciidoc/spring-boot-features.adoc | 2 +- .../boot/SpringApplicationTests.java | 14 ++-- 8 files changed, 54 insertions(+), 53 deletions(-) diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpoint.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpoint.java index 6d8f61df4fd..fce09c56148 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpoint.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpoint.java @@ -148,10 +148,12 @@ public class HalBrowserMvcEndpoint extends HalJsonMvcEndpoint return resource; } - private Resource replaceInitialLink(String contextPath, Resource resource) throws IOException { + private Resource replaceInitialLink(String contextPath, Resource resource) + throws IOException { byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream()); String content = new String(bytes, DEFAULT_CHARSET); - String initial = contextPath + getManagementServletContext().getContextPath() + getPath(); + String initial = contextPath + getManagementServletContext().getContextPath() + + getPath(); content = content.replace("entryPoint: '/'", "entryPoint: '" + initial + "'"); return new TransformedResource(resource, content.getBytes(DEFAULT_CHARSET)); } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java index 431b0e8f5e4..794adcb7475 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointManagementContextPathIntegrationTests.java @@ -92,7 +92,8 @@ public class HalBrowserMvcEndpointManagementContextPathIntegrationTests { @Test public void actuatorBrowserHtml() throws Exception { - this.mockMvc.perform(get("/admin/browser.html").accept(MediaType.APPLICATION_JSON)) + this.mockMvc + .perform(get("/admin/browser.html").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(containsString("entryPoint: '/admin'"))); } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java index e17265235f7..5ec0da75f56 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/endpoint/mvc/HalBrowserMvcEndpointServerContextPathIntegrationTests.java @@ -90,8 +90,8 @@ public class HalBrowserMvcEndpointServerContextPathIntegrationTests { HttpHeaders headers = new HttpHeaders(); headers.setAccept(Arrays.asList(MediaType.TEXT_HTML)); ResponseEntity entity = new TestRestTemplate().exchange( - "http://localhost:" + this.port + "/spring/actuator/browser.html", HttpMethod.GET, - new HttpEntity(null, headers), String.class); + "http://localhost:" + this.port + "/spring/actuator/browser.html", + HttpMethod.GET, new HttpEntity(null, headers), String.class); assertEquals(HttpStatus.OK, entity.getStatusCode()); assertTrue("Wrong body: " + entity.getBody(), entity.getBody().contains("entryPoint: '/spring/actuator'")); diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index 41ad6eba9d8..dff6b3ebe76 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -64,7 +64,8 @@ public class IntegrationAutoConfiguration { @ConditionalOnClass(EnableIntegrationMBeanExport.class) @ConditionalOnMissingBean(value = IntegrationMBeanExporter.class, search = SearchStrategy.CURRENT) @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true", matchIfMissing = true) - protected static class IntegrationJmxConfiguration implements EnvironmentAware, BeanFactoryAware { + protected static class IntegrationJmxConfiguration + implements EnvironmentAware, BeanFactoryAware { private BeanFactory beanFactory; @@ -81,7 +82,8 @@ public class IntegrationAutoConfiguration { @Override public void setEnvironment(Environment environment) { - this.propertyResolver = new RelaxedPropertyResolver(environment, "spring.jmx."); + this.propertyResolver = new RelaxedPropertyResolver(environment, + "spring.jmx."); } @Bean diff --git a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java index ec38aa346cc..47ccfac8f36 100644 --- a/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java +++ b/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandler.java @@ -36,7 +36,7 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable exception) { if (exception instanceof SilentExitException) { - if (jvmWillExit(thread)) { + if (isJvmExiting(thread)) { preventNonZeroExitCode(); } return; @@ -46,6 +46,38 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler { } } + private boolean isJvmExiting(Thread exceptionThread) { + for (Thread thread : getAllThreads()) { + if (thread != exceptionThread && thread.isAlive() && !thread.isDaemon()) { + return false; + } + } + return true; + } + + protected Thread[] getAllThreads() { + ThreadGroup rootThreadGroup = getRootThreadGroup(); + Thread[] threads = new Thread[32]; + int count = rootThreadGroup.enumerate(threads); + while (count == threads.length) { + threads = new Thread[threads.length * 2]; + count = rootThreadGroup.enumerate(threads); + } + return Arrays.copyOf(threads, count); + } + + private ThreadGroup getRootThreadGroup() { + ThreadGroup candidate = Thread.currentThread().getThreadGroup(); + while (candidate.getParent() != null) { + candidate = candidate.getParent(); + } + return candidate; + } + + protected void preventNonZeroExitCode() { + System.exit(0); + } + public static void setup(Thread thread) { UncaughtExceptionHandler handler = thread.getUncaughtExceptionHandler(); if (!(handler instanceof SilentExitExceptionHandler)) { @@ -58,41 +90,6 @@ class SilentExitExceptionHandler implements UncaughtExceptionHandler { throw new SilentExitException(); } - private boolean jvmWillExit(Thread exceptionThread) { - for (Thread thread : getAllThreads()) { - if (thread != exceptionThread && thread.isAlive() && !thread.isDaemon()) { - return false; - } - } - return true; - } - - protected void preventNonZeroExitCode() { - System.exit(0); - } - - protected Thread[] getAllThreads() { - ThreadGroup rootThreadGroup = getRootThreadGroup(); - int size = 32; - int threadCount; - Thread[] threads; - do { - size *= 2; - threads = new Thread[size]; - threadCount = rootThreadGroup.enumerate(threads); - } - while (threadCount == threads.length); - return Arrays.copyOf(threads, threadCount); - } - - private ThreadGroup getRootThreadGroup() { - ThreadGroup candidate = Thread.currentThread().getThreadGroup(); - while (candidate.getParent() != null) { - candidate = candidate.getParent(); - } - return candidate; - } - private static class SilentExitException extends RuntimeException { } diff --git a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandlerTests.java b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandlerTests.java index c9cdacae3a8..446dd13c394 100644 --- a/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandlerTests.java +++ b/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/restart/SilentExitExceptionHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2015 the original author or authors. + * Copyright 2012-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,7 @@ import static org.junit.Assert.fail; * Tests for {@link SilentExitExceptionHandler}. * * @author Phillip Webb + * @author Andy Wilkinson */ public class SilentExitExceptionHandlerTests { diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index ec311ba5c68..1ab00379309 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -1972,7 +1972,7 @@ packaged as an executable archive), there are some limitations in the JSP suppor * Undertow does not support JSPs. * Creating a custom `error.jsp` page won't override the default view for -<>. + <>. There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so you can see how to set things up. diff --git a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java index 6be89606ad9..cb779632a11 100644 --- a/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/SpringApplicationTests.java @@ -397,10 +397,9 @@ public class SpringApplicationTests { application.setBeanNameGenerator(beanNameGenerator); this.context = application.run(); verify(application.getLoader()).setBeanNameGenerator(beanNameGenerator); - assertThat( - this.context - .getBean(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR), - sameInstance((Object) beanNameGenerator)); + Object actualGenerator = this.context + .getBean(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); + assertThat(actualGenerator, sameInstance((Object) beanNameGenerator)); } @Test @@ -412,10 +411,9 @@ public class SpringApplicationTests { application.setBeanNameGenerator(beanNameGenerator); this.context = application.run(); verify(application.getLoader()).setBeanNameGenerator(beanNameGenerator); - assertThat( - this.context - .getBean(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR), - sameInstance((Object) beanNameGenerator)); + Object actualGenerator = this.context + .getBean(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); + assertThat(actualGenerator, sameInstance((Object) beanNameGenerator)); } @Test