9

I'm getting this exception:

[WARN] org.springframework.web.context.support.GenericWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private io.ilopezluna.japanathome.service.UserService io.ilopezluna.japanathome.web.rest.AccountResource.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.crypto.password.PasswordEncoder io.ilopezluna.japanathome.service.UserService.passwordEncoder; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: Cannot apply org.springframework.security.config.annotation.authentication.configurers.userdetails.DaoAuthenticationConfigurer@54aa5730 to already built object
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:293) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186) ~[spring-beans-4.0.7.RELEASE.jar:4.0.7.RELEASE]

You can see more on https://travis-ci.org/ilopezluna/japan-at-home/builds/37866955

This exception is thrown during my execution of tests. But I can't reproduce it on my localhost, I always get a build success :S

ilopezluna
  • 4,925
  • 7
  • 37
  • 66
  • Ups, sorry, updated! – ilopezluna Oct 13 '14 at 21:20
  • 1
    Do you store any configuration as a static property? Can we see `SecurityConfiguration.configureGlobal`? There is [some magic](http://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/testing.html#testcontext-ctx-management) behind Spring's context management in unit tests, so that might be broken. – Pavel Horal Oct 13 '14 at 21:29
  • sure! here you can see the method you mentioned: https://github.com/ilopezluna/japan-at-home/blob/master/src/main/java/io/ilopezluna/japanathome/config/SecurityConfiguration.java – ilopezluna Oct 13 '14 at 21:36
  • and here you can see my static data: https://github.com/ilopezluna/japan-at-home/blob/master/src/main/resources/config/liquibase/users.csv – ilopezluna Oct 13 '14 at 21:38
  • If it works on your machine but not on Travis, maybe it's a JDK issue? Are you using the same version on both? – Julien Dubois Oct 14 '14 at 12:26
  • I'm running on 1.8 and Travis on 1.7. However I already tried in my local environment using 1.7 and I get a build success – ilopezluna Oct 14 '14 at 14:29
  • Interestingly enough, we have started seeing the same thing... tests work correctly on localhost, but fail on CircleCI, with the same error as above. Were you able to solve this? – JBCP Oct 27 '14 at 18:39
  • Not yet, I tried with Codeship getting the same error. – ilopezluna Oct 27 '14 at 20:45
  • Its taken me two days, but I've tracked this down to adding a single class to my project. It doesn't seem to matter what package, or name the class has. Right now my build fails if I add `public class FooSupport { }` to any package, but works without that class. I'll update again when I have more. – JBCP Oct 28 '14 at 16:46

1 Answers1

12

It took me two days, but I believe I've finally solved this. In my SecurityConfiguration class I had the following method:

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(jsr250Enabled=true, prePostEnabled=true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(authenticationService);
    }

}

I replaced the configureGlobal method with a configure method:

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(authenticationService);
    }

And now everything works fine.

According to this answer the difference is that the using configureGlobal will allow the AuthenticationManager by global method security or another HttpSecurity (WebSecurityConfigurerAdapter).

As you can see above, I am enabling both Web Mvc Security and global method security. According to my unit tests, both continue to work with this change, but there is some debate here at my office on whether this change is correct (ie, if it is configuring global method security correctly), or if there is another problem with this solution.

We believe the root cause of the problem is some type of Spring bug, possibly a race condition. As unlikely as that seems, the problem only manifested itself when we added a empty class to the project, it didn't matter what the class's package or name was.

Community
  • 1
  • 1
JBCP
  • 11,766
  • 6
  • 67
  • 107
  • 3
    You were likely experiencing circular bean references which are not handled very well when BeanPostProcessors using (method security). If you have a sample that reproduces the issue, I'd encourage you to report a bug at https://jira.spring.io/browse/SEC/ Are you using Boot, if so it is possibly related to https://jira.spring.io/browse/SEC-2661 – Rob Winch Oct 28 '14 at 19:44
  • @RobWinch - it looks like SEC-2661 is the issue, thanks! – JBCP Oct 28 '14 at 20:53
  • SEC-2661 mentioned that "all of the `@Autowired` needs to be resolved" is key to my problem for me. Thanks, @RobWinch. – tom_mai78101 May 19 '21 at 14:48