Home > Blockchain >  Spring Boot 2.6.4 -> 2.6.6 : strange NullPointerException within Logback when logging a mock Exce
Spring Boot 2.6.4 -> 2.6.6 : strange NullPointerException within Logback when logging a mock Exce

Time:04-11

while upgrading from Spring Boot 2.6.4 to 2.6.6 , one of my tests (written in Kotlin), fails :

    @Test
    fun shouldLogProperMessageIfNotAbleToHitAPI() {

        val configValidator = ConfigValidator(GitHubCrawlerProperties(SourceControlConfig(url = "someIncorrectURL",organizationName="someOrg")),mockRemoteSourceControl)

        `when`(mockRemoteSourceControl.validateRemoteConfig("someOrg")).thenThrow(NoReachableRepositories("problem !",mock(Exception::class.java)))

        val validationErrors=configValidator.getValidationErrors()

        assertThat(validationErrors).hasSize(1);

    }

the build passes with Spring Boot 2.6.4. It works in Spring Boot 2.6.6 when I run the test individually in my IDE, but fails during the maven build.

the stacktrace was not showing by default, but after surrounding the call by a try/catch, I am able to get it, and it points to Logback :

java.lang.NullPointerException: null
        at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:99)
        at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:89)
        at ch.qos.logback.classic.spi.ThrowableProxy.<init>(ThrowableProxy.java:62)
        at ch.qos.logback.classic.spi.LoggingEvent.<init>(LoggingEvent.java:119)
        at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:419)
        at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:383)
        at ch.qos.logback.classic.Logger.error(Logger.java:538)
        at com.societegenerale.githubcrawler.ConfigValidator.getValidationErrors(ConfigValidator.kt:48)

Logback version doesn't seem to change, I still get v 1.2.11 .

Looking at Logback source code, in ThrowableProxy :

        if (GET_SUPPRESSED_METHOD != null) {
            // this will only execute on Java 7
            Throwable[] throwableSuppressed = extractSupressedThrowables(throwable);
            
            if (throwableSuppressed.length > 0) {
                List<ThrowableProxy> suppressedList = new ArrayList<ThrowableProxy>(throwableSuppressed.length);
                for (Throwable sup : throwableSuppressed) {
...

note : I build with Java 11, so the comment saying in Logback source code that this will only execute on Java 7 , seems wrong.

It seems that throwableSuppressed is null, and I get the NPE when throwableSuppressed.size is called.

The test passes if instead of using a mock in NoReachableRepositories("problem !",mock(Exception::class.java)) , I use NoReachableRepositories("problem !",Exception())

I realize it's probably better to use a real Exception rather than a mock, so my problem is solved in a way (after spending 2 hours on this..).

However, I am curious : what could cause this issue after upgrading to Spring Boot 2.6.6 which should be a a minor change ?

CodePudding user response:

This issue was introduced in logback 1.2.11 by this commit. It is tracked in this jira ticket

Logback was upgraded to 1.2.11 from spring boot 2.6.5, you can refer to this changelog. So you would have encountered this same error if you upgraded to 2.6.5.

What we can do now is to override version of logback to 1.2.10 by adding this line in build.gradle file.

ext["logback.version"] = "1.2.10"
  • Related