64

I've generated a Spring Boot web application using Spring Initializer, embedded Tomcat, Thymeleaf template engine.Technologies used: Spring Boot 1.4.2.RELEASE, Spring 4.3.4.RELEASE, Thymeleaf 2.1.5.RELEASE, Tomcat Embed 8.5.6, Maven 3, Java 8

I have an SpringBoot app. with these 2 classes:

@Profile("!war")
@SpringBootApplication
@Import({SecurityConfig.class ,PersistenceConfig.class, ServiceConfig.class})
public class BookApplication {

    public static void main(String[] args) {
        SpringApplication.run(BookApplication.class, args);
    }
}

@Profile("war")
@Import({SecurityConfig.class ,PersistenceConfig.class})
@SpringBootApplication
public class BookApplicationWar extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(BookApplicationWar.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(BookApplicationWar.class, args);
    }

}

I generate the war with this command

 mvn clean package -DskipTests -Dspring.profiles.active=pebloc,war -DAPP-KEY=pebloc

But I got this error:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) on project book: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:repackage failed: Unable to find a single main class from the following candidates [com.tdk.BookApplication, com.tdk.BookApplicationWar] -> [Help 1]
Nuñito Calzada
  • 4,394
  • 47
  • 174
  • 301

14 Answers14

55

Define single main class via start-class property

<properties>
      <start-class>com.may.Application</start-class>
</properties>

Alternatively, define the main class in the spring-boot-maven-plugin

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

Or via profiles

<profiles>
        <profile>
            <id>profile1</id>
            <properties>
                <spring.boot.mainclass>com.may.Application1</spring.boot.mainclass>
            </properties>
        </profile>
        <profile>
            <id>profile2</id>
            <properties>
                <spring.boot.mainclass>com.may.Application2</spring.boot.mainclass>
            </properties>
        </profile>
</profiles>

<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>${spring.boot.mainclass}</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
Eugene Maysyuk
  • 2,977
  • 25
  • 24
54

If you have more than one main class, you need to explicitly configure the main class in each profile:

<profiles>
    <profile>
        <id>profile1</id>
        <properties>
          <spring.boot.mainclass>com.SomeClass</spring.boot.mainclass>
        </properties>
    </profile>
    <profile>
        <id>profile2</id>
        <properties>
          <spring.boot.mainclass>com.SomeOtherClass</spring.boot.mainclass>
        </properties>
    </profile>
</profiles>

...

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.5.2.RELEASE</version>
    <executions>
      <execution>
        <goals>
          <goal>repackage</goal>
        </goals>
        <configuration>
          <mainClass>${spring.boot.mainclass}</mainClass>
        </configuration>
      </execution>
    </executions>
    ...
</plugin>

See spring-boot:repackage

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
19

To disambiguate the entry point of a spring boot application, you can add the following directive to your Gradle build file

springBoot {
    mainClassName = 'your.org.bla.TestKt'
}
Holger Brandl
  • 10,634
  • 3
  • 64
  • 63
  • 5
    Thanks for the pointer. Seems this has changed to `mainClass` only. See the docs: https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#packaging-executable.configuring.main-class – Florian Waibel Aug 17 '22 at 09:13
14

Sometimes this error is given when you do mvn install without doing mvn clean.

yılmaz
  • 1,818
  • 13
  • 15
  • 2
    Diddo for Gradle. This may happen when changing the package name when the project was already build once. In that case the clean does wonders. – Claus Oct 15 '19 at 17:33
  • 1
    Worked like a charm. Package refactoring was done, but didn't clean it. – Francis Raj Mar 10 '20 at 06:15
12

or simply hard code the main class in plugin configuration.

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <mainClass>your.main.class.MainClass</mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>
Sheikh Abdul Wahid
  • 2,623
  • 2
  • 25
  • 24
  • This doesn't work at least for me i think must be at the same level as and . @EugeneMaysyuk answer is the most concise and complete so far – Adel Ben Hamadi May 20 '23 at 12:56
10

From the command line you can use

... -Dstart-class=com.your.package.application.BookApplication
Matteo Gaggiano
  • 1,254
  • 15
  • 28
5
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) on project book: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.2.RELEASE:repackage failed: Unable to find a single main class from the following candidates [com.tdk.BookApplication, com.tdk.BookApplicationWar] 

One possible reason to getting following error is more than one main methods in your code, Spring boot allow only one main method across all class in same project.

vaquar khan
  • 10,864
  • 5
  • 72
  • 96
3

If you have a Spring Boot Application generally there is only one main class that has @SpringBootApplication , If you add another main method in the application some where , the gradle build process gets confused . So add the following at the root level of your build.gradle file

apply plugin: 'application'
mainClassName = 'packageNameAfter.srcMainJavaFolder.YourClassName'
sapy
  • 8,952
  • 7
  • 49
  • 60
2
<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>your.main.class.MainClass</mainClass>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Element configuration must be inside the plugin one!

romsky
  • 864
  • 1
  • 8
  • 11
1

I had the same error. I had renamed my Application class containing main from foo.java to bar.java, cleaned and updated. So I only ever had one main.

The error went away when I deleted the old generated class, foo.class under the target folder.

schoon
  • 2,858
  • 3
  • 46
  • 78
0

Check your application if you have multiple classes with public static void main(String[] args). Remove the one that you do not need. Specially if you generate the project with https://start.spring.io/ it comes with a class with main method in it.

If you do need all of the classes with main method just explicitly mention which one would to be boos-trapped up on application start up by mentioning it in the pom.

Tadele Ayelegn
  • 4,126
  • 1
  • 35
  • 30
0

I was building a spring boot library project, so I don't need a main starter class, so I faced the same issue while building the project with maven, so I removed the maven plugin to compile successfully

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

For a more detailed example. find it here https://spring.io/guides/gs/multi-module/

Hany Sakr
  • 2,591
  • 28
  • 27
0

You don't need to use profiles to avoid the error. You can configure the spring-boot-maven-plugin like this:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>2.6.3</version> <!-- use the corresponding version of your spring boot -->
        <executions>
            <execution>
                <id>repackage-application1</id>
                <phase>package</phase>
                <goals>
                    <goal>repackage</goal>
                </goals>
                <configuration>
                    <mainClass>com.yourpackage1.Application1</mainClass>
                    <finalName>app1</finalName>
                    <outputDirectory>target/apps</outputDirectory>
                </configuration>
            </execution>
            <execution>
                <id>repackage-application2</id>
                <phase>package</phase>
                <goals>
                    <goal>repackage</goal>
                </goals>
                <configuration>
                    <mainClass>com.yourpackage2.Application2</mainClass>
                    <finalName>app2</finalName>
                    <outputDirectory>target/apps</outputDirectory>
                </configuration>
            </execution>
        </executions>
    </plugin>

This will create app1.jar and app2.jar in your target folder.

Important note: if you inherit from spring-boot-starter-parent, it executes by default the spring-boot-maven-plugin with a default configuration that expects only one spring application. If you have two apps in a module, that default configuration will fail with the error "Unable to find a single main class" error. To fix your build you need to deactivate the default plugin execution in your parent pom. One way to do it could be to exclude a plugin in the parent pom you can take a look at maven exclude plugin defined in parent pom (did not try it myself)

i000174
  • 1,107
  • 10
  • 15
0

I defined two @SpringBootApplication on purpose. To avoid conflicts in Gradle I defined additional tasks with alternative mainClass:

tasks.named("bootRun", BootRun.class).configure {
    mainClass = "com.evil.App"
}
tasks.named("bootJar", BootJar.class).configure {
    mainClass = "com.evil.App"
}

tasks.register("bootRunH2", BootRun.class) {
    group = bootRun.group
    description = bootJar.description
    mainClass = "com.evil.H2App"
}
tasks.register("bootJarH2", BootJar.class) {
    group = bootJar.group
    description = bootJar.description
    targetJavaVersion = bootJar.targetJavaVersion
    classpath = bootJar.classpath
    mainClass = "com.evil.H2App"
}

This way you can have as many different bootRun/bootJar tasks as you wish.

gavenkoa
  • 45,285
  • 19
  • 251
  • 303