Better diagnotics when ESCF subclass breaks with custom management port
When a custom management.port is used, the child context is configured with an EmbeddedServletContainerFactory bean that has the same class as the parent context’s EmbeddedServletContainerFactory bean. This ensures that the child context uses the same type of embedded container as its parent when there are multiple embedded containers on the classpath. It also causes a failure when the custom EmbeddedServletContainerFactory subclass cannot be instantiated, for example because it’s an anonymous inner-class. This commit improves the diagnostics so that we fail fast with an information exception message when we detect that the embedded servlet container factory bean’s class cannot be instantiated. Closes gh-6193
This commit is contained in:
parent
f083447a1b
commit
6c8f8c9d82
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot.actuate.autoconfigure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.Servlet;
|
||||
|
|
@ -28,6 +29,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
|
@ -188,13 +190,12 @@ public class EndpointWebMvcAutoConfiguration
|
|||
private void registerEmbeddedServletContainerFactory(
|
||||
AnnotationConfigEmbeddedWebApplicationContext childContext) {
|
||||
try {
|
||||
EmbeddedServletContainerFactory servletContainerFactory = this.applicationContext
|
||||
.getBean(EmbeddedServletContainerFactory.class);
|
||||
ConfigurableListableBeanFactory beanFactory = childContext.getBeanFactory();
|
||||
if (beanFactory instanceof BeanDefinitionRegistry) {
|
||||
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
|
||||
registry.registerBeanDefinition("embeddedServletContainerFactory",
|
||||
new RootBeanDefinition(servletContainerFactory.getClass()));
|
||||
new RootBeanDefinition(
|
||||
determineEmbeddedServletContainerFactoryClass()));
|
||||
}
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException ex) {
|
||||
|
|
@ -202,6 +203,25 @@ public class EndpointWebMvcAutoConfiguration
|
|||
}
|
||||
}
|
||||
|
||||
private Class<?> determineEmbeddedServletContainerFactoryClass()
|
||||
throws NoSuchBeanDefinitionException {
|
||||
Class<?> servletContainerFactoryClass = this.applicationContext
|
||||
.getBean(EmbeddedServletContainerFactory.class).getClass();
|
||||
if (cannotBeInstantiated(servletContainerFactoryClass)) {
|
||||
throw new FatalBeanException("EmbeddedServletContainerFactory implementation "
|
||||
+ servletContainerFactoryClass.getName() + " cannot be instantiated. "
|
||||
+ "To allow a separate management port to be used, a top-level class "
|
||||
+ "or static inner class should be used instead");
|
||||
}
|
||||
return servletContainerFactoryClass;
|
||||
}
|
||||
|
||||
private boolean cannotBeInstantiated(Class<?> clazz) {
|
||||
return clazz.isLocalClass()
|
||||
|| (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers()))
|
||||
|| clazz.isAnonymousClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an alias for 'local.management.port' that actually resolves using
|
||||
* 'local.server.port'.
|
||||
|
|
|
|||
Loading…
Reference in New Issue