others-how to solve 'Unable to find a single main class from the following candidates' when running a spring boot application?

1. Purpose

In this post, I would demo how to solve the below error when we openning a terminal window in MacOS

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.589 s
[INFO] Finished at: 2021-05-04T13:53:19+08:00
[INFO] Final Memory: 29M/313M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:1.3.0.RELEASE:repackage (default) on project bswen2-websocket: Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.3.0.RELEASE:repackage failed: Unable to find a single main class from the following candidates [com.bswen.www2.Application, com.bswen.www2.utils.Base64] -> [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
➜  bswen2-websocket git:(use_wolib)

2. Environment

  • Mac OS 10.15
  • Spring boot 1.x and 2.x
  • Java 1.8

3. The solution

3.1 What does this error mean?

This error indicates that there are more than two classes that have main methods in your app.

image-20210507180933979

We have a spring boot application,which has a root package named com.bswen.myapp, there is a Main class inside it:

com.bswen.myapp.Main

package com.bswen.myapp;

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

And there is another class named Base64, it has a main method too.

package com.bswen.myapp;


public final class Base64 {
    public static void main(String[] args) {
        System.out.println(base64Encode("test1234^*&KJHKJ"));
        try {
            System.out.println(base64Decode(base64Encode("test1234^*&KJHKJ")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

And this is the key point:

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

Because we don’t specify the main class anywhere in the project, so the error happened.

Unable to find a single main class from the following candidates

3.2 Solution #1

You can just remove the main function in the class that is not annotated with @SpringBootApplication.

package com.bswen.myapp;

public final class Base64 {
//    public static void main(String[] args) {
//        System.out.println(base64Encode("test1234^*&KJHKJ"));
//        try {
//            System.out.println(base64Decode(base64Encode("test1234^*&KJHKJ")));
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
}

3.3 Solution #2

You can specify the main class by one of these methods:

1) In your maven pom properties
<properties>
    <!-- The main class to start by executing java -jar -->
    <start-class>com.bswen.myapp.Main</start-class>
</properties>
2) In your maven pom build plugin
<build>
  <plugins>
      <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>             
          <configuration>    
              <mainClass>com.bswen.myapp.Main</mainClass>
          </configuration>
      </plugin>
  </plugins>
</build>
3)If you use gradle

project wide build.gradle

springBoot {
    mainClass = "com.bswen.myapp.Main"
}

Or this in your module build.gradle:

bootJar {
    mainClassName = 'com.bswen.myapp.Main'
}
4) Command line

You can just specify the main class by using command line:

$ java -cp bootApp.jar -Dloader.main=com.bswen.myapp.Main org.springframework.boot.loader.PropertiesLauncher

Now it works!

4. Summary

In this post, I demonstrated how to solve Unable to find a single main class from the following candidates when running a spring boot application with more than one main classes.