http://stackoverflow.com/q/38935308/206466 I spent like 2 days trying to figure out why -Dspring.resources.static-locations wasn't working as expected (still fighting with it honestly...) all because I had @EnableWebMvc and that disables spring boot features. the fact that an Enable, disables something is hugely frustrating in its own right, but that aside I haven't noticed any warnings about it. So when using a feature that will "break" spring boot I'd like to see a warning, and maybe have a property per feature that disables said warning (if you've done that intentionally).
I spent like 2 days trying to figure out why -Dspring.resources.static-locations wasn't working as expected
This is why it pays dividends to produce a minimal, verifiable example when you've got a problem. The questions/comments that I saw included lots of information about Docker, etc, but didn't share much/any of your actual configuration.
the fact that an Enable, disables something is hugely frustrating in its own right
Aside from the wasted time, why do you find it frustrating? It's the key to Boot having strong opinions about configuration but holding them weakly so that it can get out of your way when you want to take control. Using @Enable… is how you take that control.
I get that Spring Boot is opinionated and that specific @Enable... is how you take control, I think that most of the time an @Enable... is required to actually get a feature at all... You want Spring Batch? or Spring Data JPA? how about Spring Session? OpenID AFAIK you have to @Enable them (there's another way), but that doesn't disable spring boot's default, maybe in part because those don't have defaults in spring boot. Thing is though more @Enable... annotations than not don't disable Spring Boot defaults. The docs on the annotations themselves don't say they will disable Spring Boot features because they aren't provided by Spring Boot.
I wasn't really looking at docker, I was showing evidence that the files were there (in fact I had some problems where they weren't at a couple of points because of npmignore and gitignore (speaking of surprising behavior not shipping files in gitignore...)). Thing is I was trying to think of anything that could be causing it, but I didn't notice any logs telling me why it couldn't find file X.
Sure a reproducible minimal project is a good idea, and in this case I might have been able to do it, the project is still small. In the non boot scenario I work on is a 400k line project, when something goes wrong producing a minimal project is often not viable. I'm slowly working towards making it a Boot-able project. This project is already over 2000 lines, so how do I know which of those configs are relevant? I might produce a project that works, but all that would tell me is I had a conflict which I already suspected. I didn't really think that it didn't work at all, just that it wasn't working in my situation, and that that didn't make sense to me, and I thought I was showing the relevant configuration, which was the property, and the logs showed the property was recognized, and it showed it trying to match the property. So why would I think that it wasn't working at all?
Now there are certain scenario's where I don't think adding warnings would be useful, e.g. adding an EntityManager @Bean is pretty obviously going to override a Boot Default. I'm mostly concerned about the couple of cases where @Enable disables something, because @Enable seems like a "Boot Feature", something written for the "Boot will make this easy for me" case.
as a side note there were also no warnings about file:/package/dist vs file:/package/dist/**vs file:/package/dist/. As far as I can tell the first 2 don't do what I mean.
Actually you're wrong. Taking spring session as an example, it is auto-configured and we'll back-off if you use one of the EnableXYZ of Spring Session. It's the exact same thing. The difference is that @EnableSpringMvc has a much larger scope and the relationships with message converters or static locations may not be obvious at first. But don't take control of something (don't add code) unless you really have to.
I am with Andy regarding the sample project: we do our best to monitor gitter, stackoverflow, twitter, this tracker and people pinging us privately. This is a lot of work so the least you can do is try to focus on the problem at hand and try to minimize both the dependencies and the code that actually shows the problem.
We could turn the last sentence of that section into an asciidoctor TIP. But I'm not sure that would improve the experience of developers if they don't have the reference documentation handy.
Actually you're wrong. Taking spring session as an example, it is auto-configured and we'll back-off if you use one of the EnableXYZ of Spring Session.
when was that added? (largely rhetorical) following the Spring Session docs doesn't make this obvious, I'm guessing 1.4. Even this code is an upgrade from 1.3. I've been using Boot for side projects since 1.1, and so some of these haven't always been the case.
I am with Andy regarding the sample project: we do our best to monitor gitter, stackoverflow, twitter, this tracker and people pinging us privately.
there's a gitter? I must have missed that channel in the docs.
This is a lot of work so the least you can do is try to focus on the problem at hand and try to minimize both the dependencies and the code that actually shows the problem.
Oh I can respect open source is a lot of work, I have a number of now Perl projects, that I maintained for a couple of years. Don't take this as disrespecting the support aspect. I didn't provide sufficient information to say why it wasn't working, but from the logs, I didn't know that.
the point I'm trying to reach here as I think that I should have been able to figure this out by reading the logs. But the logs made it look like it was searching that path, even at trace level.
That said I don't want to argue about this, I'm simply trying to improve this situation so I can support myself better, without having to ask for help.
We could turn the last sentence of that section into an asciidoctor TIP
that might work? I'm not sure how TIPS output... without reference documentation I'm not sure how you would figure this out currently.
https://dzone.com/articles/spring-boot-enablewebmvc-and-common-use-cases
My suggestion in situations like this is: log a warning. And require explicitly disabling autoconfiguration in order to get rid of the warning. I had to turn on debug to see what gets autoconfigured, and then explore a bunch of classes to check the necessary conditions in order to figure out the situation.
I want to just provide an example why people periodically encounter this problem and why this is actually a problem (even if it is not look as it is).
The 3-year old commit from my old project when I knew spring-boot way much worse then now:
commit 3eb3dde8a0094a27b8f284f9ac73d6d6e47cd666
Author: Ruslan Stelmachenko <[email protected]>
Date: Fri Aug 21 20:24:39 2015 +0300
Add caution to WebMvcConfig to NOT USE @EnableWebMvc
+/**
+ * <p><b>DO NOT USE @EnableWebMvc</b> as it disables spring-boot's MVC autoconfiguration.</p>
+ * For instance it disables spring-boot's jackson ObjectMapper which understands
+ * application.properties config and creates new ObjectMapper instead. This leads to
+ * LocalDateTime fields serializing as arrays instead of ISO-8601 strings.
+ *
+ * @author xakep
+ *
+ */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
It was long ago, but even today I remember that I fighting with problem that Jackson serialized LocalDateTime not way I want and some documented application.properties options (related to Jackson configuration) did not work.
At first look - for unsophisticated young developer - it was totally unrelated to @EnableWebMvc. I had no idea that this may be the cause!
I understand what @xenoterracide says. He just can't imagine that his problem was related to this annotation! (As me 3 years ago)
I spent several days until I understand what is going on and why it doesn't work. And now (looking at my commit comment) I'm not sure that I really understood that at the time of writing that comment. :)
From todays knowledge on Spring and spring-boot I understand that this behavior makes perfect sense. But for any new developer, which only learning spring-boot, this is totally unexpected (hello, Me_from_the_past).
But the leasson from this case is learned! I'll never ever forget that @EnableWebMvc is pure evil from the hell and it should be burned ASAP and never allowed to sneak into any spring-boot project. :)))
Why this annotation was added to my code at first place? I don't remember. I knew spring and spring-boot really bad at that time. I read all documentation, but it is huuuuge. Too many information for one human at one time. So it is really easy to skip the tip for @EnableWebMvc if it really was in the docs. Many guides in the internet had this annotation at that time so I think it somehow sneak into my codebase. Even today I sometimes see this annotation when my younger collegues with pure Spring background learn spring-boot. And when I ask them why they put it into their config, they says - "but this is in the docs!". They mean in Spring MVC docs...
Spring-boot is great with it's simplicity and convention-based configuration. Many developers like it for this (me too). But there is complexity under this simplicity (as always). And I think the problem with @EnableWebMvc (if I can call it that) is so often, that deserves some attention.
And I think the best way to solve it is through @EnableWebMvc javadocs. I understand, that Spring MVC is unrelated to spring-boot (actually it is way around). But... at present spring-boot is so popular, that pitfalls like this should be documented on both sides, not only on spring-boot side, if possible
I think the best way to solve it is through @EnableWebMvc javadocs.
If you search for @EnableWebMvc in the Spring Boot documentation, you end up on this section of the documentation. As a Spring Boot users, I am expecting you to look at the Spring Boot documentation when configuring things. If that section of the doc is not clear or explicit enough, I am happy to review a PR or collect your feedback in a separate issue.
@snicoll You lost the point of my comment.
The problem is that spring-boot newbie will not search for this annotation in any docs (especially if he already have experience with it from Spring background), because it will have no idea that ecountered problem somehow related to this annotation. In my 3-year-old situation I searched for ObjectMapper, Jackson, HttpMessageConverter, LocalDateTime etc (my problem was with LocalDateTime serialization), but didn't even think about that @EnableWebMvc can be the cause.
The problem that usually problems caused by having this annotation are totally unrelated (from the point of view of newbie) to this annotation. And people doesn't correlate them in any way (so, fiddle the other way to find a solution).
All these stories usually the same.
Don't take me wrong - today I absolutely understand your point. I even have my 1.5-year old answer on SO which refers to section of the spring-boot docs mentioned by you.
But spring-boot newcomers doesn't agree with you or me, that this should be obvious.
We're considering adding a property (named something like spring.mvc.use-manual-configuration) that would have to be set to allow the use of @EnableWebMvc or a user-provided bean that extends WebMvcConfigurationSupport. If the property has not been set, use of @EnableWebMvc or a WebMvcConfigurationSupport bean would throw an exception. We would use failure analysis to provide some guidance to set the property or remove the offending class/annotation.
After some more consideration, we're not convinced that the spring.mvc.use-manual-configuration flag is a good idea. Whilst I certainly understand that adding @EnableWebMvc can be a common source of problems, I'm not convinced that we should make this one specific case an exception to the rule that Spring Boot auto-configuration will back-off when you take control.
There are many other @Enabled... flags that result in similar confusing behavior and I don't think we can possibly cover them all. It feels odd that this one particular case needs an additional property to be set in order to work.
I think we must also consider that the landscape now is a little different than in 2016 when this issue was first raised. Spring Boot applications are much more common and there are many more blogs and talks that cover some of these gotchas.
Thanks to everyone that commented and voted on the issue, but for now at least, we're going to leave things as they are.
Most helpful comment
We're considering adding a property (named something like
spring.mvc.use-manual-configuration) that would have to be set to allow the use of@EnableWebMvcor a user-provided bean that extendsWebMvcConfigurationSupport. If the property has not been set, use of@EnableWebMvcor aWebMvcConfigurationSupportbean would throw an exception. We would use failure analysis to provide some guidance to set the property or remove the offending class/annotation.