Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does spring-boot @ConditionalOnClass work?

How exactly does the @ConditionalOnClass annotation work?

My goal is to load a specific bean only if the jar providing this class is included in the classpath.

I thought the I could annotate a @Bean with @ConditionalOnClass(MyService.class) and declaring the dependency in maven as optional:

<dependency>
    <groupId>de.my</groupId>
    <artifactId>my-framework<artifactId>
    <optional>true</optional>
</dependency>

@Bean
@ConditionalOnClass(MyService.class)
public MyConditionalBean statistics() {
    return new MyConditionalBean();
}

Now, anyone having my-framework as dependency should get that bean automatically wired. But anyone not having the dependency should skip it.

But when I start the app, I get the following error:

Caused by: java.lang.ClassNotFoundException: de.MyService.class
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702) ~[catalina.jar:7.0.50]
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547) ~[catalina.jar:7.0.50]

So I'm probably doing something wrong. How can I then create the bean conditional on the dependency jars and the classes contained in the classpath?

From the spring docs:

The classes that must be present. Since this annotation parsed by loading class bytecode it is safe to specify classes here that may ultimately not be on the classpath.

But the error states different...

like image 497
membersound Avatar asked Sep 06 '25 03:09

membersound


1 Answers

Good catch!

You can use on @Bean method level, but in that case you have to specify your class as a String literal:

@Bean
@ConditionalOnClass(name ="de.MyService")
public MyConditionalBean statistics() {
    return new MyConditionalBean();
}

I don't remeber already "why", but it is from an existing code of Spring Boot sources.

like image 157
Artem Bilan Avatar answered Sep 07 '25 20:09

Artem Bilan