Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

This quick tutorial provides different ways of defining an entry point into a Spring Boot application via Maven and Gradle.

A Spring Boot application’s main class is a class that contains a public static void main() method that starts up the Spring ApplicationContext. By default, if the main class isn’t explicitly specified, Spring will search for one in the classpath at compile time and fail to start if none or multiple of them are found.

Unlike in conventional Java applications, the main class discussed in this tutorial does not appear as the Main-Class metadata property in META-INF/MANIFEST.MF of the resulting JAR or WAR file.

Spring Boot expects the artifact’s Main-Class metadata property to be set to org.springframework.boot.loader.JarLauncher (or WarLauncher) which means that passing our main class directly to the java command line won’t start our Spring Boot application correctly.

An example manifest looks like this:

Manifest-Version: 1.0
Start-Class: com.baeldung.DemoApplication
Main-Class: org.springframework.boot.loader.JarLauncher

Instead, we need to define the Start-Class property in the manifest which is evaluated by JarLauncher to start the application.

Let’s see how we can control this property using Maven and Gradle.

2. Maven

The main class can be defined as a start-class element in the pom.xml‘s properties section:

<properties>
      <!-- The main class to start by executing "java -jar" -->
      <start-class>com.baeldung.DemoApplication</start-class>
</properties>

Note that this property will only be evaluated if we also add the spring-boot-starter-parent as <parent> in our pom.xml.

Alternatively, the main class can be defined as the mainClass element of the spring-boot-maven-plugin in the plugin section of our pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>             
            <configuration>    
                <mainClass>com.baeldung.DemoApplication</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

An example of this Maven configuration can be found over on GitHub.

3. Gradle

If we’re using the Spring Boot Gradle plugin, there are a few configurations inherited from org.springframework.boot where we could specify our main class.

In the project’s Gradle file, mainClassName can be defined within springBoot configuration block. This change made here is picked up by bootRun and bootJar task:

springBoot {
    mainClassName = 'cpm.baeldung.DemoApplication'
}

Alternatively, the main class can be defined as the mainClassName property of bootJar Gradle task:

bootJar {
    mainClassName = 'cpm.baeldung.DemoApplication'
}

Or as a manifest attribute of the bootJar task:

bootJar {
    manifest {
	attributes 'Start-Class': 'com.baeldung.DemoApplication'
    }
}

Note that the main class specified in the bootJar configuration block only affects the JAR that the task itself produces. The change doesn’t affect the behavior of other Spring Boot Gradle tasks such as bootRun.

As a bonus, if the Gradle application plugin is applied to the project, mainClassName can be defined as a global property:

mainClassName = 'com.baeldung.DemoApplication'

We can find an example of these Gradle configurations over on GitHub.

4. Using CLI

We can also specify a main class via the command line interface.

Spring Boot’s org.springframework.boot.loader.PropertiesLauncher comes with a JVM argument to let you override the logical main-class called loader.main:

java -cp bootApp.jar -Dloader.main=com.baeldung.DemoApplication org.springframework.boot.loader.PropertiesLauncher

5. Main Class for Different Spring Profiles

It’s quite common to use multiple Spring profiles in a Spring Boot project for specific behavior for the application. In this section, we’ll learn how to configure the entry point for such projects.

5.1. Understanding the Scenario

In a Spring Boot application, we mark the main class with the @SpringBootApplication annotation. So, by using a combination of @SpringBootApplication and @Profile annotations, we can have multiple main classes within the project. However, we must ensure that we’re activating exactly one of the profiles while running the app.

Moving forward, let’s see what happens when we try to run our application without explicitly specifying which main class to use for an active profile:

$ mvn spring-boot:run \
-Dspring.profiles.active=errorhandling \
-Perrorhandling

# output trimmed to show failure

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.1.5:run (default-cli) on project spring-boot-basic-customization: Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:2.7.11:run failed: Unable to find a single main class from the following candidates [com.baeldung.favicon.FaviconApplication, com.baeldung.failureanalyzer.FailureAnalyzerApplication, com.baeldung.errorhandling.ErrorHandlingApplication, com.baeldung.changeport.CustomApplication, com.baeldung.bootcustomfilters.SpringBootFiltersApplication] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

Unfortunately, the Spring framework fails to run the application, and it reports that it’s unable to find the main class.

No worries, there’s a well-known solution to this problem. So, let’s go ahead and learn about the fix.

5.2. Configure Main Class for Spring Profile

Firstly, we must specify the application’s entry point using the spring.boot.mainclass property for each profile in the pom.xml file:

<profiles>
    ...
    <profile>
        <id>errorhandling</id>
        <properties>
            <spring.boot.mainclass>com.baeldung.errorhandling.ErrorHandlingApplication</spring.boot.mainclass>
        </properties>
    </profile>
    ...
</profiles>

Further, we need to configure the entry point using the spring-boot-maven-plugin in the pom.xml:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>3.1.5</version>
            <configuration>
                <mainClass>${spring.boot.mainclass}</mainClass>
            </configuration>
        </plugin>
    </plugins>
</build>

Lastly, we must note that we’ve specified the mainClass in the plugin’s configuration section as the spring.boot.mainclass property value.

5.3. Running the Application

Now our project is correctly set up. So, let’s go ahead and run a specific profile of our Spring Boot project:

$ mvn spring-boot:run \
-Dspring.profiles.active=errorhandling \
-Perrorhandling

# trimmed build output
...
22:46:16.908 [main] INFO  o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 9000 (http) with context path ''
...

Fantastic! It looks like we’ve got this one right.

6. Conclusion

There are more than a few ways to specify the entry point to a Spring Boot application. It’s important to know that all these configurations are just different ways to modify the manifest of a JAR or WAR file.

Working code examples can be found here and here.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are closed on this article!