Search code examples
spring-boottomcatembedded-tomcat-8spring-boot-configurationspring-starter

How to disable SpringBoot autoconfiguration for TomcatServletWebServerFactory in order for a custom spring-starter to provide it?


so I was writing my own SpringBootStarter which was supposed to enable the JNDI lookup in the embedded tomcat of a SpringBoot application.

My sample SpringBoot application has a dependency of my custom SpringBootStarter, which in turn has a dependency on the spring-boot-starter-web. If I create a Configuration class like the following inside the sample SpringBoot application everything works perfectly:

@Configuration
public class SampleSpringBootAppConfig {


@Bean
public TomcatServletWebServerFactory tomcatFactory() {
    return new TomcatServletWebServerFactory() {
        @Override
        protected TomcatWebServer getTomcatWebServer(org.apache.catalina.startup.Tomcat tomcat) {
            System.out.println("CONFIGURING CUSTOM TOMCAT WEB SERVER FACTORY ");
            tomcat.enableNaming();
            return super.getTomcatWebServer(tomcat);
        }

        @Override
        protected void postProcessContext(Context context) {



            ContextResource resource = new ContextResource();
            resource.setName("myDataSource");
            resource.setType(DataSource.class.getName());
            resource.setProperty("driverClassName", "org.postgresql.Driver");

            resource.setProperty("url", "jdbc:postgresql://localhost:5432/postgres");
            resource.setProperty("username", "postgres");
            resource.setProperty("password", "postgres");

            context.getNamingResources()
                    .addResource(resource);

        }
    };
}

Because SpringBoot finds a custom Bean, there won't be an autoconfigured default one / it is overridden and the JNDI is successfully enabled.

However, as soon as I extract this Bean configuration into my auto-configure module of my custom SpringBoot Starter, the following exception is thrown while trying to start the sample SpringBoot application:

org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.context.ApplicationContextException: Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : tomcatServletWebServerFactory,tomcatFactory

I reckon this is due to SpringBoot not finding a customized Bean and therefore creating an autoconfigured default one which also won't be overridden. So now there will be two ServletWebServerFactory beans, the default one and the one from my auto- configure module.

What i tried so far (to no avail) :

  • annotating my custom Bean with @Primary
  • setting spring.main.allow-bean-definition-overriding to true

Is there any way to make SpringBoot not initialize a autoconfigured default bean, or any other possible solution to this?


Solution

  • I was able to solve this myself by excluding the responsible AutoConfiguration class:

    @SpringBootApplication ( exclude = ServletWebServerFactoryAutoConfiguration.class)