How to set spring.main.allow-bean-definition-overriding to true in a Spring boot 2.1.0 starter configuration












1














I maintain a spring-boot-starter that customizes the error attributes returned when, for instance, a unknown end point is called.
This is done by overriding the org.springframework.boot.web.servlet.error.ErrorAttributes bean.



Everything worked fine with 2.0.6, but 2.1.0 disables bean overriding by default, making the starter now fail with the following message.




Invalid bean definition with name 'errorAttributes' defined in class
path resource
[com/mycompany/springboot/starter/config/ErrorsConfig.class]: Cannot
register bean definition [Root bean: class [null]; scope=;
abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
autowireCandidate=true; primary=false;
factoryBeanName=com.mycompany.springboot.starter.config.ErrorsConfig;
factoryMethodName=errorAttributes; initMethodName=null;
destroyMethodName=(inferred); defined in class path resource
[com/mycompany/springboot/starter/config/ErrorsConfig.class]] for bean
'errorAttributes': There is already [Root bean: class [null]; scope=;
abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
autowireCandidate=true; primary=false;
factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
factoryMethodName=errorAttributes; initMethodName=null;
destroyMethodName=(inferred); defined in class path resource
[org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]]
bound




As explained in documentation setting the spring.main.allow-bean-definition-overriding property to true fixes the problem.
My question is how to do that in the starter (I do not want the users of my starter to have to change their application.properties file, for something that is specific to my starter)?



I tried to a @PropertySource("classpath:/com/mycompany/starter/application.properties") annotation to my @Configuration with that property defined in that file, but it doesn't work.



What am I missing? Is there any way to allow my configuration overriding that bean?



Here is the (simplified) source code of the configuration:



@Configuration
@PropertySource("classpath:/com/mycompany/starter/application.properties")
public class ErrorsConfig {
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

@Bean
public ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() {
@SuppressWarnings("unchecked")
@Override
public Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
// CustomeError is a (simplified) bean of the error attributes we should return.
CustomError err = new CustomError("myErrorCode", (String) errorAttributes.get("error"));
return OBJECT_MAPPER.convertValue(err, Map.class);
}
};
}
}


and my resource file com/mycompany/starter/application.properties contains




spring.main.allow-bean-definition-overriding=true











share|improve this question



























    1














    I maintain a spring-boot-starter that customizes the error attributes returned when, for instance, a unknown end point is called.
    This is done by overriding the org.springframework.boot.web.servlet.error.ErrorAttributes bean.



    Everything worked fine with 2.0.6, but 2.1.0 disables bean overriding by default, making the starter now fail with the following message.




    Invalid bean definition with name 'errorAttributes' defined in class
    path resource
    [com/mycompany/springboot/starter/config/ErrorsConfig.class]: Cannot
    register bean definition [Root bean: class [null]; scope=;
    abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
    autowireCandidate=true; primary=false;
    factoryBeanName=com.mycompany.springboot.starter.config.ErrorsConfig;
    factoryMethodName=errorAttributes; initMethodName=null;
    destroyMethodName=(inferred); defined in class path resource
    [com/mycompany/springboot/starter/config/ErrorsConfig.class]] for bean
    'errorAttributes': There is already [Root bean: class [null]; scope=;
    abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
    autowireCandidate=true; primary=false;
    factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
    factoryMethodName=errorAttributes; initMethodName=null;
    destroyMethodName=(inferred); defined in class path resource
    [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]]
    bound




    As explained in documentation setting the spring.main.allow-bean-definition-overriding property to true fixes the problem.
    My question is how to do that in the starter (I do not want the users of my starter to have to change their application.properties file, for something that is specific to my starter)?



    I tried to a @PropertySource("classpath:/com/mycompany/starter/application.properties") annotation to my @Configuration with that property defined in that file, but it doesn't work.



    What am I missing? Is there any way to allow my configuration overriding that bean?



    Here is the (simplified) source code of the configuration:



    @Configuration
    @PropertySource("classpath:/com/mycompany/starter/application.properties")
    public class ErrorsConfig {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Bean
    public ErrorAttributes errorAttributes() {
    return new DefaultErrorAttributes() {
    @SuppressWarnings("unchecked")
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
    Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
    // CustomeError is a (simplified) bean of the error attributes we should return.
    CustomError err = new CustomError("myErrorCode", (String) errorAttributes.get("error"));
    return OBJECT_MAPPER.convertValue(err, Map.class);
    }
    };
    }
    }


    and my resource file com/mycompany/starter/application.properties contains




    spring.main.allow-bean-definition-overriding=true











    share|improve this question

























      1












      1








      1







      I maintain a spring-boot-starter that customizes the error attributes returned when, for instance, a unknown end point is called.
      This is done by overriding the org.springframework.boot.web.servlet.error.ErrorAttributes bean.



      Everything worked fine with 2.0.6, but 2.1.0 disables bean overriding by default, making the starter now fail with the following message.




      Invalid bean definition with name 'errorAttributes' defined in class
      path resource
      [com/mycompany/springboot/starter/config/ErrorsConfig.class]: Cannot
      register bean definition [Root bean: class [null]; scope=;
      abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
      autowireCandidate=true; primary=false;
      factoryBeanName=com.mycompany.springboot.starter.config.ErrorsConfig;
      factoryMethodName=errorAttributes; initMethodName=null;
      destroyMethodName=(inferred); defined in class path resource
      [com/mycompany/springboot/starter/config/ErrorsConfig.class]] for bean
      'errorAttributes': There is already [Root bean: class [null]; scope=;
      abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
      autowireCandidate=true; primary=false;
      factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
      factoryMethodName=errorAttributes; initMethodName=null;
      destroyMethodName=(inferred); defined in class path resource
      [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]]
      bound




      As explained in documentation setting the spring.main.allow-bean-definition-overriding property to true fixes the problem.
      My question is how to do that in the starter (I do not want the users of my starter to have to change their application.properties file, for something that is specific to my starter)?



      I tried to a @PropertySource("classpath:/com/mycompany/starter/application.properties") annotation to my @Configuration with that property defined in that file, but it doesn't work.



      What am I missing? Is there any way to allow my configuration overriding that bean?



      Here is the (simplified) source code of the configuration:



      @Configuration
      @PropertySource("classpath:/com/mycompany/starter/application.properties")
      public class ErrorsConfig {
      private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

      @Bean
      public ErrorAttributes errorAttributes() {
      return new DefaultErrorAttributes() {
      @SuppressWarnings("unchecked")
      @Override
      public Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
      Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
      // CustomeError is a (simplified) bean of the error attributes we should return.
      CustomError err = new CustomError("myErrorCode", (String) errorAttributes.get("error"));
      return OBJECT_MAPPER.convertValue(err, Map.class);
      }
      };
      }
      }


      and my resource file com/mycompany/starter/application.properties contains




      spring.main.allow-bean-definition-overriding=true











      share|improve this question













      I maintain a spring-boot-starter that customizes the error attributes returned when, for instance, a unknown end point is called.
      This is done by overriding the org.springframework.boot.web.servlet.error.ErrorAttributes bean.



      Everything worked fine with 2.0.6, but 2.1.0 disables bean overriding by default, making the starter now fail with the following message.




      Invalid bean definition with name 'errorAttributes' defined in class
      path resource
      [com/mycompany/springboot/starter/config/ErrorsConfig.class]: Cannot
      register bean definition [Root bean: class [null]; scope=;
      abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
      autowireCandidate=true; primary=false;
      factoryBeanName=com.mycompany.springboot.starter.config.ErrorsConfig;
      factoryMethodName=errorAttributes; initMethodName=null;
      destroyMethodName=(inferred); defined in class path resource
      [com/mycompany/springboot/starter/config/ErrorsConfig.class]] for bean
      'errorAttributes': There is already [Root bean: class [null]; scope=;
      abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0;
      autowireCandidate=true; primary=false;
      factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
      factoryMethodName=errorAttributes; initMethodName=null;
      destroyMethodName=(inferred); defined in class path resource
      [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]]
      bound




      As explained in documentation setting the spring.main.allow-bean-definition-overriding property to true fixes the problem.
      My question is how to do that in the starter (I do not want the users of my starter to have to change their application.properties file, for something that is specific to my starter)?



      I tried to a @PropertySource("classpath:/com/mycompany/starter/application.properties") annotation to my @Configuration with that property defined in that file, but it doesn't work.



      What am I missing? Is there any way to allow my configuration overriding that bean?



      Here is the (simplified) source code of the configuration:



      @Configuration
      @PropertySource("classpath:/com/mycompany/starter/application.properties")
      public class ErrorsConfig {
      private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

      @Bean
      public ErrorAttributes errorAttributes() {
      return new DefaultErrorAttributes() {
      @SuppressWarnings("unchecked")
      @Override
      public Map<String, Object> getErrorAttributes(WebRequest request, boolean includeStackTrace) {
      Map<String, Object> errorAttributes = super.getErrorAttributes(request, includeStackTrace);
      // CustomeError is a (simplified) bean of the error attributes we should return.
      CustomError err = new CustomError("myErrorCode", (String) errorAttributes.get("error"));
      return OBJECT_MAPPER.convertValue(err, Map.class);
      }
      };
      }
      }


      and my resource file com/mycompany/starter/application.properties contains




      spring.main.allow-bean-definition-overriding=true








      spring-boot spring-boot-configuration






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 23 '18 at 17:33









      Jean-Marc Astesana

      7421819




      7421819
























          1 Answer
          1






          active

          oldest

          votes


















          3














          Spring Boot's ErrorAttributes bean is defined by ErrorMvcAutoConfiguration. It is annotated with @ConditionalOnMissingBean so it will back off if an ErrorAttributes bean has already been defined. As the bean defined by your ErrorsConfig class is attempting to override Boot's ErrorAttributes bean rather than causing it to back off, your ErrorsConfig class must be getting processed after Boot's ErrorMvcAutoConfiguration class. This means that you have an ordering problem in your starter.



          The order in which auto-configuration classes are processed can be controlled using @AutoConfigureBefore and @AutoConfigureAfter. Assuming that ErrorsConfig is itself an auto-configuration class registered in spring.factories, you can fix your problem by annotating it with @AutoConfigureBefore(ErrorMvcAutoConfiguration.class). With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot's ErrorsAttribute bean to back off.






          share|improve this answer























          • Thank's a lot, that work very well :-)
            – Jean-Marc Astesana
            Nov 23 '18 at 23:00











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450897%2fhow-to-set-spring-main-allow-bean-definition-overriding-to-true-in-a-spring-boot%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          Spring Boot's ErrorAttributes bean is defined by ErrorMvcAutoConfiguration. It is annotated with @ConditionalOnMissingBean so it will back off if an ErrorAttributes bean has already been defined. As the bean defined by your ErrorsConfig class is attempting to override Boot's ErrorAttributes bean rather than causing it to back off, your ErrorsConfig class must be getting processed after Boot's ErrorMvcAutoConfiguration class. This means that you have an ordering problem in your starter.



          The order in which auto-configuration classes are processed can be controlled using @AutoConfigureBefore and @AutoConfigureAfter. Assuming that ErrorsConfig is itself an auto-configuration class registered in spring.factories, you can fix your problem by annotating it with @AutoConfigureBefore(ErrorMvcAutoConfiguration.class). With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot's ErrorsAttribute bean to back off.






          share|improve this answer























          • Thank's a lot, that work very well :-)
            – Jean-Marc Astesana
            Nov 23 '18 at 23:00
















          3














          Spring Boot's ErrorAttributes bean is defined by ErrorMvcAutoConfiguration. It is annotated with @ConditionalOnMissingBean so it will back off if an ErrorAttributes bean has already been defined. As the bean defined by your ErrorsConfig class is attempting to override Boot's ErrorAttributes bean rather than causing it to back off, your ErrorsConfig class must be getting processed after Boot's ErrorMvcAutoConfiguration class. This means that you have an ordering problem in your starter.



          The order in which auto-configuration classes are processed can be controlled using @AutoConfigureBefore and @AutoConfigureAfter. Assuming that ErrorsConfig is itself an auto-configuration class registered in spring.factories, you can fix your problem by annotating it with @AutoConfigureBefore(ErrorMvcAutoConfiguration.class). With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot's ErrorsAttribute bean to back off.






          share|improve this answer























          • Thank's a lot, that work very well :-)
            – Jean-Marc Astesana
            Nov 23 '18 at 23:00














          3












          3








          3






          Spring Boot's ErrorAttributes bean is defined by ErrorMvcAutoConfiguration. It is annotated with @ConditionalOnMissingBean so it will back off if an ErrorAttributes bean has already been defined. As the bean defined by your ErrorsConfig class is attempting to override Boot's ErrorAttributes bean rather than causing it to back off, your ErrorsConfig class must be getting processed after Boot's ErrorMvcAutoConfiguration class. This means that you have an ordering problem in your starter.



          The order in which auto-configuration classes are processed can be controlled using @AutoConfigureBefore and @AutoConfigureAfter. Assuming that ErrorsConfig is itself an auto-configuration class registered in spring.factories, you can fix your problem by annotating it with @AutoConfigureBefore(ErrorMvcAutoConfiguration.class). With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot's ErrorsAttribute bean to back off.






          share|improve this answer














          Spring Boot's ErrorAttributes bean is defined by ErrorMvcAutoConfiguration. It is annotated with @ConditionalOnMissingBean so it will back off if an ErrorAttributes bean has already been defined. As the bean defined by your ErrorsConfig class is attempting to override Boot's ErrorAttributes bean rather than causing it to back off, your ErrorsConfig class must be getting processed after Boot's ErrorMvcAutoConfiguration class. This means that you have an ordering problem in your starter.



          The order in which auto-configuration classes are processed can be controlled using @AutoConfigureBefore and @AutoConfigureAfter. Assuming that ErrorsConfig is itself an auto-configuration class registered in spring.factories, you can fix your problem by annotating it with @AutoConfigureBefore(ErrorMvcAutoConfiguration.class). With this change in place ErrorsConfig will define its ErrorAttributes bean before ErrorMvcAutoConfiguration attempts to do so which will cause the auto-configuration of Boot's ErrorsAttribute bean to back off.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 23 '18 at 23:11

























          answered Nov 23 '18 at 20:00









          Andy Wilkinson

          56.6k9136145




          56.6k9136145












          • Thank's a lot, that work very well :-)
            – Jean-Marc Astesana
            Nov 23 '18 at 23:00


















          • Thank's a lot, that work very well :-)
            – Jean-Marc Astesana
            Nov 23 '18 at 23:00
















          Thank's a lot, that work very well :-)
          – Jean-Marc Astesana
          Nov 23 '18 at 23:00




          Thank's a lot, that work very well :-)
          – Jean-Marc Astesana
          Nov 23 '18 at 23:00


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53450897%2fhow-to-set-spring-main-allow-bean-definition-overriding-to-true-in-a-spring-boot%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)