209
Execution default of goal 
org.springframework.boot:spring-boot-maven-plugin:1.0.1.RELEASE:repackage 
failed: 
Unable to find a single main class from the following candidates

My project has more than one class with a main method. How do I tell the Spring Boot Maven plugin which of the classes it should use as the main class?

Thilo
  • 257,207
  • 101
  • 511
  • 656

11 Answers11

299

Add your start class in your pom:

<properties>
    <!-- The main class to start by executing java -jar -->
    <start-class>com.mycorp.starter.HelloWorldApplication</start-class>
</properties>

or

<build>
<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>             
        <configuration>    
            <mainClass>com.mycorp.starter.HelloWorldApplication</mainClass>
        </configuration>
    </plugin>
</plugins>
</build>
raj240
  • 646
  • 7
  • 17
ludo_rj
  • 3,877
  • 1
  • 18
  • 37
  • No need to disable anything. Or am I missing something? – Dave Syer Apr 22 '14 at 12:23
  • 32
    Note that this answer is correct if you use the spring-boot-starter-parent pom. In that case the "start-class" property is applied to the "mainClass" configuration parameter of the spring-boot-maven-plugin (which you can do directly if you aren't using the starter). – Dave Syer Apr 22 '14 at 13:16
  • 19
    Thanks @ludo_rj, and I found this also works: `mvn clean package -Dstart-class=com.foo.Application`, if want to dynamically specify using which main class – zhuguowei May 11 '16 at 06:16
  • 5
    One more thing to add, the parameter mentioned by @zhuguowei is also valid for the Spring Boot Maven Plugin: `mvn spring-boot:run -Dstart-class=com.foo.Application`. This is valid only if you haven't specified the mainClass in the pom's plugin – Gerardo Roza Dec 04 '18 at 12:27
  • Both did not work for me. I also thought it was an "AND" not an or? I see the Start-Class: correctly in the MANIFEST.MF, but spring starts a different annotated @SpringBootApplication main class. I actually need that class for bootstrapping some things so I do not really like to change the annotation. Simply removing it did not work anyway. Spring seems to start the first main() it finds. I'm using spring-boot-starter-parent 2.2.0.M3. – Angel O'Sphere Oct 07 '19 at 12:30
140

For those using Gradle (instead of Maven) :

springBoot {
    mainClass = "com.example.Main"
}
Marcelo C.
  • 3,822
  • 2
  • 22
  • 11
  • 3
    Spring Boot 2.x gives an error `Could not set unknown property 'mainClass' for object of type org.springframework.boot.gradle.dsl.SpringBootExtension`. – Thunderforge Jul 06 '18 at 20:15
  • The answer is down this page: https://stackoverflow.com/a/49716696/75672 – Vitalik Jul 09 '18 at 14:28
71

If you do NOT use the spring-boot-starter-parent pom, then from the Spring documentation:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.1.3.RELEASE</version>
    <configuration>
        <mainClass>my.package.MyStartClass</mainClass>
        <layout>ZIP</layout>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Renaud
  • 16,073
  • 6
  • 81
  • 79
26

For those using Gradle (instead of Maven), referencing Spring Boot Gradle Plugin Reference Guide (as of Gradle 7.6 and Spring Boot 3.0.0):

The main class can also be configured explicitly using the task’s mainClass property:

tasks.named("bootJar") {
  mainClass = 'com.example.ExampleApplication'
}

Alternatively, the main class name can be configured project-wide using the mainClass property of the Spring Boot DSL:

springBoot {
  mainClass = 'com.example.ExampleApplication'
}
andrybak
  • 2,129
  • 2
  • 20
  • 40
Shane Lu
  • 1,056
  • 1
  • 12
  • 21
  • Oh my goodness. This is the needle in the haystack I've been looking for .. for 2 days now. Thank you. This answer (https://stackoverflow.com/a/67519950/214977) gave me the HINT to search for.. what you have here. and THANK YOU for providing your gradle and SB versions in the answer. The lack of versions (in other answers) drives me nutso. – granadaCoder Jun 21 '23 at 17:19
  • For future readers.. I was able to use the "tasks.named" from this answer.. to get "Implementation-Version" to show up in my Manifest.MF of a spring-boot-application with gradle. While gradle was creating a Manifest.MF file and it had "spring boot'ish" values in it, I was stuck getting some "well known" attributes in there. My next comment will be the gradle/groovy code that I used. But basically this helped me with "How to get "Implementation-Version" to work in a gradle springboot project. – granadaCoder Jun 21 '23 at 17:44
  • /* magic (below) to get explicit values to show up in Manifest.MF file in a spring-boot-app. "Implementation-Version" drives Package.getImplementationVersion functionality */ tasks.named("bootJar") { manifest { attributes( "Implementation-Title": "HardCodedName123", "Implementation-Version": "HardCodedVersion234", 'Build-Date': new Date().format("yyyy-MM-dd"), 'Build-Time': new Date().format("HH:mm:ssZ") ) } } – granadaCoder Jun 21 '23 at 17:45
  • Note, my gradle/groovy code was in the "top layer" gradle module of a multiple module gradle project. I do not build single layer monoliths. – granadaCoder Jun 21 '23 at 17:46
15

If you're using spring-boot-starter-parent in your pom, you simply add the following to your pom:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Then do your mvn package.

See this Spring docs page.

A very important aspect here is to mention that the directory structure has to be src/main/java/nameofyourpackage

Community
  • 1
  • 1
mojave
  • 415
  • 6
  • 11
  • I found this solution to work without modifying the pom.xml once I replicated the package requirements for the .java classes. –  Mar 04 '16 at 19:57
6

I tried the following code in pom.xml and it worked for me

<build>
<plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
            <mainClass>myPackage.HelloWorld</mainClass> 
        </configuration>
    </plugin>
    <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <fork>true</fork>
            <executable>D:\jdk1.8\bin\javaw.exe</executable>
        </configuration>
    </plugin>
</plugins>

TRIDIB BOSE
  • 391
  • 3
  • 3
  • I tried to use the spring-boot-maven-plugin configuration you mentionned in my multimodules maven project, composed by several Spring boot projects and including Spring Boot as BOM dependency, and it worked like a charm. Concerning the maven-compiler-plugin, I didn't specify anything as I don't want my POM platform dependent. Maven automatically forked, so I think you can just ignore this configuration. – Cheloute Oct 25 '17 at 15:40
5

Since Spring Boot 1.5, you can complete ignore the error-prone string literal in pom or build.gradle. The repackaging tool (via maven or gradle plugin) will pick the one annotated with @SpringBootApplication for you. (Refer to this issue for detail: https://github.com/spring-projects/spring-boot/issues/6496 )

Thilo
  • 257,207
  • 101
  • 511
  • 656
tan9
  • 3,490
  • 2
  • 18
  • 21
3

I had renamed my project and it was still finding the old Application class on the build path. I removed it in the 'build' folder and all was fine.

Anthony De Smet
  • 2,265
  • 3
  • 17
  • 24
1

Have seen this issue with Java 1.9 and SpringBoot 1.5.x, when main-class is not specified explicitly.

With Java 1.8, it is able to find main-class without explicit property and 'mvn package' works fine.

dy10
  • 117
  • 1
  • 8
1

If you are using Grade, it is possible to apply the 'application' plugin rather than the 'java' plugin. This allows specifying the main class as below without using any Spring Boot Gradle plugin tasks.

plugins {
  id 'org.springframework.boot' version '2.3.3.RELEASE'
  id 'io.spring.dependency-management' version '1.0.10.RELEASE'
  id 'application'
}
application {
  mainClassName = 'com.example.ExampleApplication'
}

As a nice benefit, one is able to run the application using gradle run with the classpath automatically configured by Gradle. The plugin also packages the application as a TAR and/or ZIP including operating system specific start scripts.

dbaltor
  • 2,737
  • 3
  • 24
  • 36
1

For Kotlin with Gradle:

springBoot {
  mainClass.set("com.example.MainKt")
}
flashback
  • 383
  • 3
  • 6