Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Complete
    • Affects Version/s: 4.2.2
    • Fix Version/s: 4.2.3
    • Component/s: Core
    • Labels:
    • Last commented by a User:
      false

      Description

      After switching to 4.2.2 I get the following exception during autowiring:

      Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String de.ei.janet.server.Janet.saDir; nested exception is java.lang.NullPointerException
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:571) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	... 29 common frames omitted
      Caused by: java.lang.NullPointerException: null
      	at java.util.concurrent.ConcurrentHashMap.containsValue(ConcurrentHashMap.java:979) ~[na:1.8.0_60]
      	at java.util.concurrent.ConcurrentHashMap$ValuesView.contains(ConcurrentHashMap.java:4664) ~[na:1.8.0_60]
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.determineAutowireCandidate(DefaultListableBeanFactory.java:1228) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1124) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:543) ~[spring-beans-4.2.2.RELEASE.jar:4.2.2.RELEASE]
      	... 31 common frames omitted
      

      The reason seams to be the last changes in DefaultListableBeanFactory (Commit 097bcfb997bd215c7b39635770e34812744f0d9e). This commit replaces HashMap with ConcurrentHashMap. After this change the fallback case in method determineAutowireCandidate throws the NullPointerException if beanInstance is null.

        Activity

        Hide
        snicoll Stéphane Nicoll added a comment -

        Could you please share a sample project that exhibits the problem?

        Show
        snicoll Stéphane Nicoll added a comment - Could you please share a sample project that exhibits the problem?
        Hide
        mrs22 Michael Schoene added a comment -

        Upload samle project to github: https://github.com/mrs2207/spr-13599.git

        Show
        mrs22 Michael Schoene added a comment - Upload samle project to github: https://github.com/mrs2207/spr-13599.git
        Hide
        snicoll Stéphane Nicoll added a comment -

        Thanks for the sample project. A few remarks:

        • the PropertySourcesPlaceholderConfigurer is actually useless.
        • You are autowiring a collaborator in the Spring Boot application itself so we are forced to eagerly initialize it. If I move those two strings to a separate service, the application runs fine. We are recommending not to inject dependencies in the Spring Boot application class itself.

        Since it is a Spring Boot sample, I'd be tempted to move that issue in the Spring Boot tracker, but I'd like Juergen Hoeller to have a look first.

        Show
        snicoll Stéphane Nicoll added a comment - Thanks for the sample project. A few remarks: the PropertySourcesPlaceholderConfigurer is actually useless. You are autowiring a collaborator in the Spring Boot application itself so we are forced to eagerly initialize it. If I move those two strings to a separate service, the application runs fine. We are recommending not to inject dependencies in the Spring Boot application class itself. Since it is a Spring Boot sample, I'd be tempted to move that issue in the Spring Boot tracker, but I'd like Juergen Hoeller to have a look first.
        Hide
        mrs22 Michael Schoene added a comment -

        I updated my sample project (move the autowired strings to a separate service). The exception is still being thrown.

        Why is the PropertySourcesPlaceholderConfigurer useless? Without this bean and the line

        pspc.setNullValue( "@null" );
        

        the @null default value in the Properties class does not work as expected.

        Show
        mrs22 Michael Schoene added a comment - I updated my sample project (move the autowired strings to a separate service). The exception is still being thrown. Why is the PropertySourcesPlaceholderConfigurer useless? Without this bean and the line pspc.setNullValue( "@null" ); the @null default value in the Properties class does not work as expected.
        Hide
        juergen.hoeller Juergen Hoeller added a comment -

        On review, there seems to be an issue with our use of containsValue here: Even if our Map never holds a null value, we must not call containsValue with a null - which would return false in any case but is not supported that way by ConcurrentHashMap. And since bean instances may be null in certain rare cases, we need to be defensive there. To be addressed for 4.2.3 (due in about two weeks).

        Juergen

        Show
        juergen.hoeller Juergen Hoeller added a comment - On review, there seems to be an issue with our use of containsValue  here: Even if our Map never holds a null value, we must not call containsValue with a null - which would return false  in any case but is not supported that way by ConcurrentHashMap . And since bean instances may be null in certain rare cases, we need to be defensive there. To be addressed for 4.2.3 (due in about two weeks). Juergen
        Hide
        juergen.hoeller Juergen Hoeller added a comment -

        Turns out that my assumption was right: The presence of a nullreturning FactoryBean whose getObjectType() result matches a given injection point, with more than one matching bean present, can lead to a NullPointerException if there is no primary match otherwise... e.g. if the FactoryBean result would be chosen based on a bean name match. I've added a unit test for this and made the determineAutowireCandidate more defensive now, simply through only calling ConcurrentHashMap.contains in case of a nonnull bean instance.

        A general lesson here: It's not sufficient to check whether a given Map may actually contain null values before turning it into a ConcurrentHashMap (or other impl which doesn't allow null values). We also need to make sure that nobody calls containsValue / values().contains with a null argument since such impls will throw a hard NPE there.

        Juergen

        Show
        juergen.hoeller Juergen Hoeller added a comment - Turns out that my assumption was right: The presence of a null returning FactoryBean whose getObjectType() result matches a given injection point, with more than one matching bean present, can lead to a NullPointerException if there is no primary match otherwise... e.g. if the FactoryBean result would be chosen based on a bean name match. I've added a unit test for this and made the determineAutowireCandidate more defensive now, simply through only calling ConcurrentHashMap.contains in case of a non null bean instance. A general lesson here: It's not sufficient to check whether a given Map may actually contain null values before turning it into a ConcurrentHashMap (or other impl which doesn't allow null values). We also need to make sure that nobody calls containsValue / values().contains with a null argument since such impls will throw a hard NPE there. Juergen

          People

          • Assignee:
            juergen.hoeller Juergen Hoeller
            Reporter:
            mrs22 Michael Schoene
            Last updater:
            Stéphane Nicoll
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              2 years, 17 weeks, 5 days ago