Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strage behaviour in DelegatingWebMvcConfiguration with 1.3.0.M5 #4154

Closed
benneq opened this issue Oct 12, 2015 · 14 comments
Closed

Strage behaviour in DelegatingWebMvcConfiguration with 1.3.0.M5 #4154

benneq opened this issue Oct 12, 2015 · 14 comments
Milestone

Comments

@benneq
Copy link

benneq commented Oct 12, 2015

Hi, I've got a strange problem with DelegatingWebMvcConfiguration:

When I start our project without Spring Security ( @SpringBootApplication(exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class) ), everything is normal.
But when I enable Spring Security (by removing the exclude), I figured out, that DelegatingWebMvcConfiguration's @Autowired(required = false) public void setConfigurers(List<WebMvcConfigurer> configurers) method is getting called AFTER its protected void addFormatters(FormatterRegistry registry) method.

I can't figure out why this is happening. I tried to setup an extremely small test project, but there everything works as expected. I thought that @Autowired setters get called immediately after the constructor and before any other method can be invoked?

Thanks for your help.

@philwebb
Copy link
Member

I would expect autowired methods to get called before @Bean methods such as mvcConversionService (which triggers addFormatters). Without a project that replicates the issue it's very hard to tell what's going on.

Perhaps you could add some breakpoints to those methods and attach details of the call stack? That might give us some clues.

@philwebb philwebb added the status: waiting-for-feedback We need additional information before we can continue label Oct 12, 2015
@philwebb
Copy link
Member

BTW is this something that you see behaving differently between 1.3.0.M5 and 1.2.6?

@benneq
Copy link
Author

benneq commented Oct 13, 2015

Thanks for the hint. I now tried 1.2.6.RELEASE (with default spring.version 4.1.7 and with spring.version 4.2.1) and I get exactly the same behavior: frist addFormatters, then setConfigurers.

I already got breakpoints in both methods, but there's some EnhancerBySpringCGLIB magic going on, and I can't really tell what's going on, because Eclipse can't open those files.

I now just ran the not-working version with Boot 1.3.0.M5 and here is what I could copy from Eclipse debugger:

  1. call to setFormatters: http://pastebin.com/4MXnYwdf
  2. call to setConfigurers: http://pastebin.com/tG7CsHJM

If I can give you any better information, please tell me. Sadly I can't share the project. If you can't get any useful information from the Stacks, I think I'm gonna remove classes one by one till it's working as expected, and then should be able to share a stripped down project that shows the misbehavior.

@philwebb
Copy link
Member

I think something is causing early instantiation of WebMvcAutoConfiguration but it's still not clear what. The most likely candidate is SpelExpression.getValue(EvaluationContext) line: 242.

Can you work up the stacktrace from SpelExpression to see what the parameters are passed to evaluateBeanDefinitionString. We really need to know what bean is triggering all this.

@benneq
Copy link
Author

benneq commented Oct 13, 2015

This sounds like there's some problem with the @SpelAssert validation annotation i'm using: https://github.com/jirutka/validator-spring
I will remove this dependency and let you know

@benneq
Copy link
Author

benneq commented Oct 13, 2015

It wasn't the dependency. Though I just spent the last 3 hours with deleting code and starting and stopping the application 😆
Now there are just a few files left and I can upload the code. I also found out where you can toggle that strange behavior, but not why that happens. I'll upload the code later this afternoon.

@benneq
Copy link
Author

benneq commented Oct 13, 2015

Here's the code: http://pastebin.com/JcU5Y5vL
And my pom.xml: http://pastebin.com/K5MKq2ww


I added two break points within DelegatingWebMvcConfiguration:
1. at the setConfigurers method
2. at the addFormatters method

Additionally I added a simple@RestController for testing purpose which tries to call my custom converter, but can't find it. No converter found capable of converting from type test.Application$MyClass to type test.Application$YourClass.


Within the code I made two comments: #1 and #2. These are the places I found where you can switch the strange behavior on and off.
#1: Just add exclude=org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration.class to turn off Spring Security and it works. (removing spring security from pom.xml also works)
#2: Turn the @Autowired ConversionService conversionService; into a @Lazy autowireing.

As a workaround I can use of course @Lazy @Autowired. But it would be really interesting why this happens and if it can be solved in a clean way.

Thanks in advance!

@philwebb
Copy link
Member

It appears that the SpEL expression is from Spring Security. The WebSecurityConfiguration.setFilterChainProxySecurityConfigurer method calls autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers(). This in turn gets all WebSecurityConfigurer beans.

One such bean is org.springframework.boot.autoconfigure.security.SpringBootWebSecurityConfiguration$ApplicationWebSecurityConfigurerAdapter. For some reason this injects mvcContentNegotiationManager which then triggers the whole process.

@philwebb
Copy link
Member

/cc @rwinch @dsyer

philwebb added a commit that referenced this issue Oct 14, 2015
Update SecurityFilterAutoConfiguration to use a DelegatingFilterProxy
filter rather directly referencing the springSecurityFilterChain bean.

Using a DelegatingFilterProxy helps to prevent early initialization of
beans and makes Spring Security work in a similar to way to if were
installed in a regular WAR deployment.

Fixes gh-4154
@philwebb
Copy link
Member

@benneq Can you try the latest 1.3.0.BUILD-SNAPSHOT to see if we've managed to fix this?

philwebb added a commit to philwebb/spring-boot that referenced this issue Oct 14, 2015
Update SecurityFilterAutoConfiguration to use a DelegatingFilterProxy
filter rather directly referencing the springSecurityFilterChain bean.

Using a DelegatingFilterProxy helps to prevent early initialization of
beans and makes Spring Security work in a similar to way to if were
installed in a regular WAR deployment.

Fixes spring-projectsgh-4154
@rwinch
Copy link
Member

rwinch commented Oct 16, 2015

@philwebb I was able to try the latest SNAPSHOT and can confirm your changes resolved this issue for me.

@benneq
Copy link
Author

benneq commented Oct 19, 2015

Ah sorry, haven't seen your question. But I'm glad that this bug will be gone in 1.3.0.RC1 👍

@philwebb philwebb added this to the 1.3.0.RC1 milestone Oct 19, 2015
@philwebb philwebb removed the status: waiting-for-feedback We need additional information before we can continue label Oct 19, 2015
@benneq
Copy link
Author

benneq commented Oct 21, 2015

Tested it with 1.3.0.RC1 and it works! Thank you!

@wilkinsona
Copy link
Member

@benneq Thanks for testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants