Adam Arold
Adam Arold

Reputation: 30568

How to completely disable Spring Boot Autoconfiguration?

I'm working on an app and I only want to use Spring's DI features. My problem is that I can't manage to disable Spring Boot's autoconfiguration features. I keep getting this exception:

2020-06-26 14:00:03.240 [main] TRACE o.s.b.diagnostics.FailureAnalyzers - Failed to load org.springframework.boot.autoconfigure.jdbc.HikariDriverConfigurationFailureAnalyzer
java.lang.NoClassDefFoundError: org/springframework/jdbc/CannotGetJdbcConnectionException
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
    at java.lang.Class.getConstructor0(Class.java:3075)
    at java.lang.Class.getDeclaredConstructor(Class.java:2178)
    at org.springframework.boot.diagnostics.FailureAnalyzers.loadFailureAnalyzers(FailureAnalyzers.java:75)
    at org.springframework.boot.diagnostics.FailureAnalyzers.<init>(FailureAnalyzers.java:66)
    at org.springframework.boot.diagnostics.FailureAnalyzers.<init>(FailureAnalyzers.java:60)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:204)
    at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:441)
    at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:427)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
    at MyApplication.main(MyApplication.java:19)

I tried not using @SpringBootApplication only @ComponentScan, but it didn't work. I also tried excluding the relevant autoconfiguration classes:

@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        JdbcTemplateAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class,
        XADataSourceAutoConfiguration.class})
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication .class, args);
    }
}

but this is not working either. How can I get rid of autoconfiguration completely? I didn't find a @DisableAutoConfiguration annotation, yet there is a @EnableAutoConfiguration.

Edit:

My beans are configured in a separate file in the same package as my application class:

@Configuration
public class BeanConfig {

    @Bean
    public Database database() {
        return DatabaseConfig.configureDatabase();
    }

    @Bean
    public UserRepository userRepository() {
        return new InMemoryUserRepository(
                Collections.singletonList(new UserEntity(
                        1,
                        "user",
                        Arrays.asList(Permission.ADOPT.name(), Permission.EDIT_PROFILE.name()))));
    }

    @DependsOn("database")
    @Bean
    public DogRepository dogRepository() {
        return new H2DogRepository();
    }

    @Bean
    public AdoptDog adoptDog() {
        return new AdoptDog(dogRepository());
    }

    @Bean
    public FindDogs findDogs() {
        return new FindDogs(dogRepository());
    }

    @Bean
    public CreateDog createDog() {
        return new CreateDog(dogRepository());
    }

    @Bean
    public DeleteDogs deleteDogs() {
        return new DeleteDogs(dogRepository());
    }

    @Bean
    public FindUser findUser() {
        return new FindUser(userRepository());
    }

    @PostConstruct
    public void initialize() {
        ApplicationEngine engine = ServerConfig.configureServer(
                userRepository(), adoptDog(), findDogs(), createDog(), findUser(), deleteDogs());
        DogUtils.loadDogs().forEach(dogRepository()::create);
        CheckerUtils.runChecks(engine, userRepository());
    }
}

I have a different server technology, and I'm using this project to demonstrate Kotlin-Java interoperability (all these files are Kotlin files which are referenced here).

Upvotes: 1

Views: 4123

Answers (3)

Add only spring-boot to dependencies (don't use *-starter-*)

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot</artifactId>
    </dependency>

, and use @ComponentScan instead of @SpringBootApplication.

Upvotes: 2

Adam Arold
Adam Arold

Reputation: 30568

The problem was that Spring was looking for classes which I didn't have (I'm not using any of them) but was necessary for it to work.

Once I added "org.springframework.boot:spring-boot-starter-data-jdbc" and "javax.validation:validation-api:2.0.1.Final" as dependencies it started to work.

Upvotes: 2

Actually this may be down to spring.factories in some of your jars and authors violating it. (i.e not listing them under the key of EnableAutoConfiguration as per https://docs.spring.io/autorepo/docs/spring-boot/2.0.0.M3/reference/html/boot-features-developing-auto-configuration.html

In this example, an Application Listener will be registered regardless of auto config enabled or not. May be some of the jars in your class path have beans defined in spring factories https://www.logicbig.com/tutorials/spring-framework/spring-boot/application-listener-via-spring-factories.html

Upvotes: 1

Related Questions