Search code examples
javaspringspring-bootmaven

How to Run Spring Boot Application with Unpacked Dependencies?


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?


Solution

  • 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