1

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).

1
  • Before spring Boot came along we could only do what you want to do… it's been a long time for me, I used to work on spring-mvc applications. The key thing is just to kick off an application context. With spring-mvc that was triggered by the servlet lifecycle but you can just create one from a main method or any other hook point that works for you. I haven't got anything to hand but there must be non-boot spring examples in spring's documentation
    – Chris
    Commented Jun 26, 2020 at 12:14

3 Answers 3

2

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.

0
2

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.

1

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

2
  • I tried not using @SpringBootApplication only @ComponentScan, but it didn't work.
    – Adam Arold
    Commented Jun 26, 2020 at 12:15
  • The problem is that some classes are not on the classpath that Spring tries to use, but it shouldn't touch them at all because I only want to use the DI features.
    – Adam Arold
    Commented Jun 26, 2020 at 12:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.