Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maven uses 'start-class' when the parent POM is being used and ignores 'spring-boot.run.main-class' #40145

Closed
siddhsql opened this issue Apr 1, 2024 · 9 comments
Assignees
Labels
type: bug A general bug
Milestone

Comments

@siddhsql
Copy link

siddhsql commented Apr 1, 2024

I wrote a spring application with multiple main classes. When I try to run it as follows:

mvn spring-boot:run \
 -Dspring-boot.run.profiles=profile2 \
 -Dspring-boot.run.main-class=com.example.demo.DemoApplication2

I get this error:

Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.1.5:run failed: Unable to find a single main class from the following candidates [com.example.demo.DemoApplication2, com.example.demo.DemoApplication]

If I remove the following from my pom.xml:

<parent>	
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.5</version>
    <relativePath/> 
</parent>

then it works! seems like a bug.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Apr 1, 2024
@scottfrederick
Copy link
Contributor

Thanks for getting in touch. Unfortunately, you have not provided enough information for us to be able to help you. If you would like us to spend some time investigating, please provide a complete minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it and attaching it to this issue.

@scottfrederick scottfrederick added the status: waiting-for-feedback We need additional information before we can continue label Apr 1, 2024
@codespearhead
Copy link

codespearhead commented Apr 1, 2024

The correct flag is -Dstart-class, not -Dspring-boot.run.main-class.

Minimal Reproducible Example

  1. Create a demo Spring Boot project:
mkdir demo &&
cd demo &&
curl https://start.spring.io/starter.tgz -d type=maven-project | tar -xzvf -
  1. Delete the main class
rm src/main/java/com/example/demo/DemoApplication.java
  1. Create two main classes (DemoApplication1.java and DemoApplication2.java):
cat > src/main/java/com/example/demo/DemoApplication1.java <<EOF && cat > src/main/java/com/example/demo/DemoApplication2.java <<EOF
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication1 {

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

}
EOF
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication2 {

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

}
EOF
  1. Run the project:
  • Error path:
./mvnw spring-boot:run
# Or: ./mvnw spring-boot:run -Dspring-boot.run.main-class=com.example.demo.DemoApplication1
# Or: ./mvnw spring-boot:run -Dspring-boot.run.main-class=com.example.demo.DemoApplication2
  • Happy path:
./mvnw spring-boot:run -Dstart-class=com.example.demo.DemoApplication1
# Or: ./mvnw spring-boot:run -Dstart-class=com.example.demo.DemoApplication2

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Apr 1, 2024
@siddhsql
Copy link
Author

siddhsql commented Apr 1, 2024

attached MRE as zipped file
issue40145.zip

If the correct flag is -Dstart-class then couple of questions wait to be begged:

  1. Why is it not documented in official documentation? Official documentation says to use -Dspring-boot.run.main-class [1]

  2. Why does the -Dspring-boot.run.main-class flag work when I don't use following in pom.xml:

<parent>	
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>3.2.4</version>
	<relativePath/> 
</parent>

@codespearhead
Copy link

Upon closer inspection, you're right: you shouldn't have to resort to a JVM system property (start-class) when there's already an allegedly setting for development convenience (spring-boot.run.main-class).

However, here's what Bael Dung has to say:

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.
[...]
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.

Hence, I stand corrected: this is a bug in my opinion.

@philwebb philwebb added the for: team-meeting An issue we'd like to discuss as a team to make progress label Apr 4, 2024
@philwebb philwebb changed the title Execution default-cli of goal org.springframework.boot:spring-boot-maven-plugin:3.1.5:run failed: Unable to find a single main class from the following candidates [com.example.demo.DemoApplication2, com.example.demo.DemoApplication] Maven uses 'start-class' when the parent POM is being used and ignores 'spring-boot.run.main-class' Apr 4, 2024
@philwebb
Copy link
Member

philwebb commented Apr 4, 2024

This is an interesting problem and I'm not sure how to best solve it. Our spring-boot-starter-parent POM configures a few plugins (including spring-boot-maven-plugin) to use a ${start-class} variable. It seems that even if that variable isn't set, the act of configuring the plugin in the XML disables support for the spring-boot.run.main-class property.

We'll need to discuss this some more to work out what we should do.

@siddhsql

This comment was marked as abuse.

@codespearhead

This comment was marked as outdated.

@mhalbritter
Copy link
Contributor

If we add this in our parent:

    <properties>
        <spring-boot.run.main-class>${start-class}</spring-boot.run.main-class>
    </properties>

and then change the config of the spring-boot-maven-plugin in the parent:

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <mainClass>${spring-boot.run.main-class}</mainClass>
                </configuration>
            </plugin>

then both start-class and spring-boot.run.main-class would work.

@philwebb
Copy link
Member

philwebb commented Apr 4, 2024

The other plugins we configure with ${start-class} are:

  • maven-jar-plugin
  • maven-war-plugin
  • maven-shade-plugin

I don't think any of those have -D properties that the user can set. Given that, I think we should try the approach @mhalbritter suggests above. Since it's a little risky, and there is a work-around, we'll do this in 3.3.x.

@philwebb philwebb added type: bug A general bug and removed status: waiting-for-triage An issue we've not yet triaged status: feedback-provided Feedback has been provided for: team-meeting An issue we'd like to discuss as a team to make progress labels Apr 4, 2024
@philwebb philwebb added this to the 3.3.x milestone Apr 4, 2024
@mhalbritter mhalbritter self-assigned this Apr 5, 2024
@mhalbritter mhalbritter modified the milestones: 3.3.x, 3.3.0-RC1 Apr 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug A general bug
Projects
None yet
Development

No branches or pull requests

6 participants