From 5147fcacdf9c8a65f53be47afd816bfb1e8dda90 Mon Sep 17 00:00:00 2001 From: Scott Frederick Date: Tue, 15 Jun 2021 17:40:48 -0500 Subject: [PATCH] Improve BeanNotOfRequiredTypeFailureAnalyzer output This commit modifies the output of BeanNotOfRequiredTypeFailureAnalyzer to include type information for both the actual and the required types and to remove ambiguity. Fixes gh-26821 --- .../BeanNotOfRequiredTypeFailureAnalyzer.java | 11 ++++++++--- .../BeanNotOfRequiredTypeFailureAnalyzerTests.java | 10 +++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzer.java index d48f1e5ecf..43ec018d5b 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -29,6 +29,7 @@ import org.springframework.boot.diagnostics.FailureAnalysis; * {@link BeanNotOfRequiredTypeException}. * * @author Andy Wilkinson + * @author Scott Frederick * @since 1.4.0 */ public class BeanNotOfRequiredTypeFailureAnalyzer extends AbstractFailureAnalyzer { @@ -48,8 +49,12 @@ public class BeanNotOfRequiredTypeFailureAnalyzer extends AbstractFailureAnalyze private String getDescription(BeanNotOfRequiredTypeException ex) { StringWriter description = new StringWriter(); PrintWriter printer = new PrintWriter(description); - printer.printf("The bean '%s' could not be injected as a '%s' because it is a " - + "JDK dynamic proxy that implements:%n", ex.getBeanName(), ex.getRequiredType().getName()); + printer.printf("The bean '%s' could not be injected because it is a JDK dynamic proxy%n%n", ex.getBeanName()); + printer.printf("The bean is of type '%s' and implements:%n", ex.getActualType().getName()); + for (Class actualTypeInterface : ex.getActualType().getInterfaces()) { + printer.println("\t" + actualTypeInterface.getName()); + } + printer.printf("%nExpected a bean of type '%s' which implements:%n", ex.getRequiredType().getName()); for (Class requiredTypeInterface : ex.getRequiredType().getInterfaces()) { printer.println("\t" + requiredTypeInterface.getName()); } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzerTests.java index f247a1b9e0..38b35dde38 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/BeanNotOfRequiredTypeFailureAnalyzerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2021 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. @@ -35,6 +35,7 @@ import static org.junit.jupiter.api.Assertions.fail; * Tests for {@link BeanNotOfRequiredTypeFailureAnalyzer}. * * @author Andy Wilkinson + * @author Scott Frederick */ class BeanNotOfRequiredTypeFailureAnalyzerTests { @@ -44,8 +45,11 @@ class BeanNotOfRequiredTypeFailureAnalyzerTests { void jdkProxyCausesInjectionFailure() { FailureAnalysis analysis = performAnalysis(JdkProxyConfiguration.class); assertThat(analysis.getDescription()).startsWith("The bean 'asyncBean'"); - assertThat(analysis.getDescription()).contains("'" + AsyncBean.class.getName() + "'"); - assertThat(analysis.getDescription()).endsWith(String.format("%s%n", SomeInterface.class.getName())); + assertThat(analysis.getDescription()) + .containsPattern("The bean is of type '" + AsyncBean.class.getPackage().getName() + ".\\$Proxy.*'"); + assertThat(analysis.getDescription()).contains("and implements:\n\t" + SomeInterface.class.getName()); + assertThat(analysis.getDescription()).contains("Expected a bean of type '" + AsyncBean.class.getName() + "'"); + assertThat(analysis.getDescription()).contains("which implements:\n\t" + SomeInterface.class.getName()); } private FailureAnalysis performAnalysis(Class configuration) {