diff --git a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzer.java b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzer.java index 10978e96c8..af9a9821ce 100644 --- a/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzer.java +++ b/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzer.java @@ -37,6 +37,18 @@ class NoSuchMethodFailureAnalyzer extends AbstractFailureAnalyzer candidates, - URL actual) { + private String getDescription(NoSuchMethodError cause, NoSuchMethodDescriptor descriptor) { StringWriter description = new StringWriter(); PrintWriter writer = new PrintWriter(description); writer.println("An attempt was made to call a method that does not" @@ -111,11 +125,12 @@ class NoSuchMethodFailureAnalyzer extends AbstractFailureAnalyzer candidateLocations; + + private final URL actualLocation; + + public NoSuchMethodDescriptor(String errorMessage, String className, List candidateLocations, + URL actualLocation) { + this.errorMessage = errorMessage; + this.className = className; + this.candidateLocations = candidateLocations; + this.actualLocation = actualLocation; + } + + public String getErrorMessage() { + return this.errorMessage; + } + + public String getClassName() { + return this.className; + } + + public List getCandidateLocations() { + return this.candidateLocations; + } + + public URL getActualLocation() { + return this.actualLocation; + } + + } + } diff --git a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzerTests.java b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzerTests.java index 628941e3fb..ad0f3fc89f 100644 --- a/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzerTests.java +++ b/spring-boot-project/spring-boot/src/test/java/org/springframework/boot/diagnostics/analyzer/NoSuchMethodFailureAnalyzerTests.java @@ -25,6 +25,7 @@ import org.junit.jupiter.api.condition.EnabledOnJre; import org.junit.jupiter.api.condition.JRE; import org.springframework.boot.diagnostics.FailureAnalysis; +import org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer.NoSuchMethodDescriptor; import org.springframework.boot.testsupport.classpath.ClassPathOverrides; import static org.assertj.core.api.Assertions.assertThat; @@ -34,10 +35,53 @@ import static org.mockito.Mockito.mock; * Tests for {@link NoSuchMethodFailureAnalyzer}. * * @author Andy Wilkinson + * @author Stephane Nicoll */ @ClassPathOverrides("javax.servlet:servlet-api:2.5") class NoSuchMethodFailureAnalyzerTests { + @Test + void parseJava8ErrorMessage() { + NoSuchMethodDescriptor descriptor = new NoSuchMethodFailureAnalyzer().getNoSuchMethodDescriptor( + "javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)" + + "Ljavax/servlet/ServletRegistration$Dynamic;"); + assertThat(descriptor).isNotNull(); + assertThat(descriptor.getErrorMessage()) + .isEqualTo("javax.servlet.ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)" + + "Ljavax/servlet/ServletRegistration$Dynamic;"); + assertThat(descriptor.getClassName()).isEqualTo("javax.servlet.ServletContext"); + assertThat(descriptor.getCandidateLocations()).isNotEmpty(); + assertThat(descriptor.getActualLocation()).asString().contains("servlet-api-2.5.jar"); + } + + @Test + void parseJava13OpenJ9ErrorMessage() { + NoSuchMethodDescriptor descriptor = new NoSuchMethodFailureAnalyzer().getNoSuchMethodDescriptor( + "javax/servlet/ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)" + + "Ljavax/servlet/ServletRegistration$Dynamic; (loaded from file..."); + assertThat(descriptor).isNotNull(); + assertThat(descriptor.getErrorMessage()) + .isEqualTo("javax/servlet/ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)" + + "Ljavax/servlet/ServletRegistration$Dynamic;"); + assertThat(descriptor.getClassName()).isEqualTo("javax.servlet.ServletContext"); + assertThat(descriptor.getCandidateLocations()).isNotEmpty(); + assertThat(descriptor.getActualLocation()).asString().contains("servlet-api-2.5.jar"); + } + + @Test + void parseJava13HotspotErrorMessage() { + NoSuchMethodDescriptor descriptor = new NoSuchMethodFailureAnalyzer().getNoSuchMethodDescriptor( + "'javax.servlet.ServletRegistration$Dynamic javax.servlet.ServletContext.addServlet(" + + "java.lang.String, javax.servlet.Servlet)'"); + assertThat(descriptor).isNotNull(); + assertThat(descriptor.getErrorMessage()) + .isEqualTo("'javax.servlet.ServletRegistration$Dynamic javax.servlet.ServletContext.addServlet(" + + "java.lang.String, javax.servlet.Servlet)'"); + assertThat(descriptor.getClassName()).isEqualTo("javax.servlet.ServletContext"); + assertThat(descriptor.getCandidateLocations()).isNotEmpty(); + assertThat(descriptor.getActualLocation()).asString().contains("servlet-api-2.5.jar"); + } + @Test @EnabledOnJre({ JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_12 }) void noSuchMethodErrorIsAnalyzedJava8To12() { @@ -50,8 +94,8 @@ class NoSuchMethodFailureAnalyzerTests { @DisabledOnJre({ JRE.JAVA_8, JRE.JAVA_11, JRE.JAVA_12 }) void noSuchMethodErrorIsAnalyzedJava13AndLater() { testNoSuchMethodErrorFailureAnalysis( - "javax/servlet/ServletContext.addServlet(Ljava/lang/String;Ljavax/servlet/Servlet;)" - + "Ljavax/servlet/ServletRegistration$Dynamic;"); + "'javax.servlet.ServletRegistration$Dynamic javax.servlet.ServletContext.addServlet(" + + "java.lang.String, javax.servlet.Servlet)'"); } private void testNoSuchMethodErrorFailureAnalysis(String expectedMethodRepresentation) {