Revert "Add failure analyzer for BeanCreationException"
Closes gh-9220
This commit is contained in:
		
							parent
							
								
									07ec13d454
								
							
						
					
					
						commit
						08a8bb0f8b
					
				| 
						 | 
					@ -1,58 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright 2012-2017 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.
 | 
					 | 
				
			||||||
 * You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
 * See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
 * limitations under the License.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package org.springframework.boot.diagnostics.analyzer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.springframework.beans.factory.BeanCreationException;
 | 
					 | 
				
			||||||
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
 | 
					 | 
				
			||||||
import org.springframework.boot.diagnostics.FailureAnalysis;
 | 
					 | 
				
			||||||
import org.springframework.boot.diagnostics.FailureAnalyzer;
 | 
					 | 
				
			||||||
import org.springframework.core.annotation.Order;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * A {@link FailureAnalyzer} that performs analysis of failures caused by a
 | 
					 | 
				
			||||||
 * {@link BeanCreationException}.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Stephane Nicoll
 | 
					 | 
				
			||||||
 * @see BeanCurrentlyInCreationFailureAnalyzer
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
@Order(100)
 | 
					 | 
				
			||||||
public class BeanCreationFailureAnalyzer
 | 
					 | 
				
			||||||
		extends AbstractFailureAnalyzer<BeanCreationException> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
					 | 
				
			||||||
	protected FailureAnalysis analyze(Throwable rootFailure,
 | 
					 | 
				
			||||||
			BeanCreationException cause) {
 | 
					 | 
				
			||||||
		StringBuilder sb = new StringBuilder();
 | 
					 | 
				
			||||||
		sb.append("A bean named '").append(cause.getBeanName()).append("'");
 | 
					 | 
				
			||||||
		if (cause.getResourceDescription() != null) {
 | 
					 | 
				
			||||||
			sb.append(" defined in ").append(cause.getResourceDescription());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		sb.append(" failed to be created:");
 | 
					 | 
				
			||||||
		sb.append(String.format("%n%n"));
 | 
					 | 
				
			||||||
		Throwable nested = findMostNestedCause(cause);
 | 
					 | 
				
			||||||
		sb.append(String.format("\t%s", nested.getMessage()));
 | 
					 | 
				
			||||||
		return new FailureAnalysis(sb.toString(), null, cause);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Throwable findMostNestedCause(Throwable exception) {
 | 
					 | 
				
			||||||
		if (exception.getCause() == null) {
 | 
					 | 
				
			||||||
			return exception;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return findMostNestedCause(exception.getCause());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,6 @@ import org.springframework.beans.factory.InjectionPoint;
 | 
				
			||||||
import org.springframework.beans.factory.UnsatisfiedDependencyException;
 | 
					import org.springframework.beans.factory.UnsatisfiedDependencyException;
 | 
				
			||||||
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
 | 
					import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
 | 
				
			||||||
import org.springframework.boot.diagnostics.FailureAnalysis;
 | 
					import org.springframework.boot.diagnostics.FailureAnalysis;
 | 
				
			||||||
import org.springframework.core.annotation.Order;
 | 
					 | 
				
			||||||
import org.springframework.util.StringUtils;
 | 
					import org.springframework.util.StringUtils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -34,7 +33,6 @@ import org.springframework.util.StringUtils;
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @author Andy Wilkinson
 | 
					 * @author Andy Wilkinson
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@Order(0)
 | 
					 | 
				
			||||||
class BeanCurrentlyInCreationFailureAnalyzer
 | 
					class BeanCurrentlyInCreationFailureAnalyzer
 | 
				
			||||||
		extends AbstractFailureAnalyzer<BeanCurrentlyInCreationException> {
 | 
							extends AbstractFailureAnalyzer<BeanCurrentlyInCreationException> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,6 @@ org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Failure Analyzers
 | 
					# Failure Analyzers
 | 
				
			||||||
org.springframework.boot.diagnostics.FailureAnalyzer=\
 | 
					org.springframework.boot.diagnostics.FailureAnalyzer=\
 | 
				
			||||||
org.springframework.boot.diagnostics.analyzer.BeanCreationFailureAnalyzer,\
 | 
					 | 
				
			||||||
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
 | 
					org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
 | 
				
			||||||
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
 | 
					org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
 | 
				
			||||||
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
 | 
					org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -805,6 +805,25 @@ public class SpringApplicationTests {
 | 
				
			||||||
						TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME);
 | 
											TestPropertySourceUtils.INLINED_PROPERTIES_PROPERTY_SOURCE_NAME);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						public void failureResultsInSingleStackTrace() throws Exception {
 | 
				
			||||||
 | 
							ThreadGroup group = new ThreadGroup("main");
 | 
				
			||||||
 | 
							Thread thread = new Thread(group, "main") {
 | 
				
			||||||
 | 
								@Override
 | 
				
			||||||
 | 
								public void run() {
 | 
				
			||||||
 | 
									SpringApplication application = new SpringApplication(
 | 
				
			||||||
 | 
											FailingConfig.class);
 | 
				
			||||||
 | 
									application.setWebEnvironment(false);
 | 
				
			||||||
 | 
									application.run();
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							thread.start();
 | 
				
			||||||
 | 
							thread.join(6000);
 | 
				
			||||||
 | 
							int occurrences = StringUtils.countOccurrencesOf(this.output.toString(),
 | 
				
			||||||
 | 
									"Caused by: java.lang.RuntimeException: ExpectedError");
 | 
				
			||||||
 | 
							assertThat(occurrences).as("Expected single stacktrace").isEqualTo(1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Condition<ConfigurableEnvironment> matchingPropertySource(
 | 
						private Condition<ConfigurableEnvironment> matchingPropertySource(
 | 
				
			||||||
			final Class<?> propertySourceClass, final String name) {
 | 
								final Class<?> propertySourceClass, final String name) {
 | 
				
			||||||
		return new Condition<ConfigurableEnvironment>("has property source") {
 | 
							return new Condition<ConfigurableEnvironment>("has property source") {
 | 
				
			||||||
| 
						 | 
					@ -947,6 +966,16 @@ public class SpringApplicationTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Configuration
 | 
				
			||||||
 | 
						static class FailingConfig {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							@Bean
 | 
				
			||||||
 | 
							public Object fail() {
 | 
				
			||||||
 | 
								throw new RuntimeException("ExpectedError");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Configuration
 | 
						@Configuration
 | 
				
			||||||
	static class CommandLineRunConfig {
 | 
						static class CommandLineRunConfig {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,84 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright 2012-2017 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.
 | 
					 | 
				
			||||||
 * You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 *      http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
 * See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
 * limitations under the License.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
package org.springframework.boot.diagnostics.analyzer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.junit.Test;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.springframework.boot.diagnostics.FailureAnalysis;
 | 
					 | 
				
			||||||
import org.springframework.boot.diagnostics.FailureAnalyzer;
 | 
					 | 
				
			||||||
import org.springframework.context.ConfigurableApplicationContext;
 | 
					 | 
				
			||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 | 
					 | 
				
			||||||
import org.springframework.context.annotation.Bean;
 | 
					 | 
				
			||||||
import org.springframework.context.annotation.Configuration;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
					 | 
				
			||||||
import static org.junit.Assert.fail;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Tests for {@link BeanCreationFailureAnalyzer}.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * @author Stephane Nicoll
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
public class BeanCreationFailureAnalyzerTest {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private final FailureAnalyzer analyzer = new BeanCreationFailureAnalyzer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Test
 | 
					 | 
				
			||||||
	public void failureWithDefinition() {
 | 
					 | 
				
			||||||
		FailureAnalysis analysis = performAnalysis(
 | 
					 | 
				
			||||||
				BeanCreationFailureConfiguration.class);
 | 
					 | 
				
			||||||
		assertThat(analysis.getDescription()).contains("bean named 'foo'",
 | 
					 | 
				
			||||||
				"Property bar is not set",
 | 
					 | 
				
			||||||
				"defined in " + BeanCreationFailureConfiguration.class.getName());
 | 
					 | 
				
			||||||
		assertThat(analysis.getDescription()).doesNotContain("Failed to instantiate");
 | 
					 | 
				
			||||||
		assertThat(analysis.getAction()).isNull();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private FailureAnalysis performAnalysis(Class<?> configuration) {
 | 
					 | 
				
			||||||
		FailureAnalysis analysis = this.analyzer.analyze(createFailure(configuration));
 | 
					 | 
				
			||||||
		assertThat(analysis).isNotNull();
 | 
					 | 
				
			||||||
		return analysis;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	private Exception createFailure(Class<?> configuration) {
 | 
					 | 
				
			||||||
		ConfigurableApplicationContext context = null;
 | 
					 | 
				
			||||||
		try {
 | 
					 | 
				
			||||||
			context = new AnnotationConfigApplicationContext(configuration);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		catch (Exception ex) {
 | 
					 | 
				
			||||||
			return ex;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		finally {
 | 
					 | 
				
			||||||
			if (context != null) {
 | 
					 | 
				
			||||||
				context.close();
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		fail("Expected failure did not occur");
 | 
					 | 
				
			||||||
		return null;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Configuration
 | 
					 | 
				
			||||||
	static class BeanCreationFailureConfiguration {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		@Bean
 | 
					 | 
				
			||||||
		public String foo() {
 | 
					 | 
				
			||||||
			throw new IllegalStateException("Property bar is not set");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Loading…
	
		Reference in New Issue