I have a simple Spring Boot application that starts HTTP server:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I compiled it and copied all its dependencies into a classes
folder using the unpack-dependencies
goal:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.6.1</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludes>
module-info.class
</excludes>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Then I try to run the application directly without building a jar
file:
java -cp "target/classes" my.Application
However, when I try to start the application using the following command, Spring Boot can't seem to load the required dependencies. The application starts and finishes immediately without starting the HTTP server.
If I run the following command:
mvn spring-boot:run
The application starts successfully. I checked the logs and found out that when I use the mvn spring-boot:run
command, Spring Boot uses dependencies from the .m2
folder, so probably it doesn’t use unpacked dependencies from the classes
folder.
Is it possible to start a Spring Boot application without building a jar
archive and using unpacked dependencies? What am I missing in how I specify the classpath
for a Spring Boot application with its dependencies?
Spring Boot uses spring.factories
configuration files in its ‘starter' dependencies to determine which configurations to initialize for an application.
Since I copied and unpacked all the dependencies into the single target/classes
directory, I overwrote the target/classes/META-INF/spring.factories
file from several Spring Boot starters multiple times.
As a result, when I started my application, it used an incorrect spring.factories
file and, therefore, incorrect beans.
To avoid this issue, I explicitly added the required spring.factories
file to the target/classes/META-INF
directory. If you are using Maven, then you can add the spring.factories
file to src/main/resources
, and after running mvn package
, you will find it under target/classes/META-INF
.
You can read more about the spring.factories
file here and here