I have a typical Spring Boot REST server:
…
@SpringBootApplication
public class MyService {
public static void main(String[] args) {
SpringApplication.run(MyService.class, args);
}
}
I include org.springframework.boot:spring-boot-starter-web
along with de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring30x
in order to embed MongoDB for testing and running in the IDE. This application starts fine from the resulting JAR file.
However I want to disable automatically configuring the embedded MongoDB server; instead I want to enable it based only on certain profiles. My first step is to exclude EmbeddedMongoAutoConfiguration
:
…
import de.flapdoodle.embed.mongo.spring.autoconfigure.EmbeddedMongoAutoConfiguration;
@SpringBootApplication(exclude = {EmbeddedMongoAutoConfiguration.class})
public class MyService {
public static void main(String[] args) {
SpringApplication.run(MyService.class, args);
}
}
So far so good—the application still runs. Now I want to make sure that the embedded MongoDB classes don't get distributed with the application, because I plan to only enable EmbeddedMongoAutoConfiguration
in the IDE (based on a profile). So I update my POM like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<excludeGroupIds>de.flapdoodle,de.flapdoodle.embed,de.flapdoodle.graph,
de.flapdoodle.java8,de.flapdoodle.reverse</excludeGroupIds>
</configuration>
</execution>
</executions>
</plugin>
Suddenly the application no longer starts up, saying:
***************************
APPLICATION FAILED TO START
***************************
Description:
Web application could not be started as there was no org.springframework.boot.web.servlet.server.ServletWebServerFactory bean defined in the context.
Action:
Check your application's dependencies for a supported servlet web server.
Check the configured web application type.
Why does excluding unused class files prevent the application from defining a ServletWebServerFactory
?
My guess is that when I indicate @SpringBootApplication(exclude = {EmbeddedMongoAutoConfiguration.class})
, Spring will get confused if the EmbeddedMongoAutoConfiguration
class is not present. Instead of thinking, "hey, the class doesn't even exist, so I don't have to do anything to exclude it", Spring instead thinks, "I want to exclude this class, but it's not even present, so I don't know what to do!" And instead of producing an error and saying "I can't create the application", it simply doesn't create the necessary beans, and leaves it to later for the application to say, "uh oh, I don't have a ServletWebServerFactory
and I have no idea why not".
Does anyone know a way that I can dynamically exclude EmbeddedMongoAutoConfiguration
in a way that way that won't confused Spring if EmbeddedMongoAutoConfiguration
is in fact not even present in the distribution?