-
Notifications
You must be signed in to change notification settings - Fork 109
Description
What version of OpenRewrite are you using?
I am using
- Maven plugin v6.22.1
- rewirte-migrate-java:RELEASE
How are you running OpenRewrite?
I am using the Maven plugin without any configuration just by running the goal via
mvn -U org.openrewrite.maven:rewrite-maven-plugin:run -Drewrite.recipeArtifactCoordinates=org.openrewrite.recipe:rewrite-migrate-java:RELEASE -Drewrite.activeRecipes=org.openrewrite.java.migrate.UpgradeToJava25 -Drewrite.exportDatatables=true
What is the smallest, simplest way to reproduce the problem?
I basically found three examples when running the UpgradeToJava25 receipt, which are all related to the OpenRewrite recipe for JEP 512 instance main methods which was introduced within #852.
- Empty Spring Boot Project
Currently, Spring Boot, at least with Maven, when building its executable JAR file uses the public static void main(String[] args) Signature for detecting which class to use as its main entry point.
This can be reproduced by generating an empty Spring Boot Maven Project (via https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.5.6&packaging=jar&jvmVersion=21&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=) and executing the OpenRewrite receipt for upgrading to Java 25. Afterwards when calling mvn verify the build fails with: `
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.5.6:repackage (repackage) on project demo: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:3.5.6:repackage failed: Unable to find main class -> [Help 1]
- Main method is used as a method reference
The following code:
public class MainMethodReferenced {
public static void main(String[] args) {
}
@FunctionalInterface
interface MainMethod {
void run(String[] args);
}
static void someOtherMethod() {
MainMethod foo = MainMethodReferenced::main;
foo.run(null);
}
}
relies on the main-Method being static and receiving the args. But after the migration it no longer compiles.
Although, on first sight, this seems to be an unusable use-case, it is the default when using Spring Boot with Testcontainers support.
If you use start.spring.io and select testcontainers as dependency (see https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.5.6&packaging=jar&jvmVersion=21&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=testcontainers) by default within the test java sources a class TestDemoApplication is created that contains a main-Method that uses the real applications main-Method as a method reference.
- main-Method on class with non default constructor
The last use case was a CLI tool that in its main-Method creates an instance of itself and delegates to another method, like:
public class MainWithNonDefaultConstructor {
public static void main(String[] args) {
}
public MainWithNonDefaultConstructor(String[] args) {}
}
After the receipt is run, this class compiles, but it can't be executed because a default constructor is missing.
I think 2. and 3. can probably be fixed by improving the receipt to check for the presence of a default constructor / usage as a method reference.
Number 1 is a tougher one to detect. Most likely impossible.
I would therefore suggest that the “JEP 512 instance main methods”-receipt should not be included in any Spring Boot Update receipt unless instance-main-Methods are supported by default within Spring Boot.
And most likely, not including that receipt within the UpgradeToJava25 might be a good idea, too?
Are you interested in contributing a fix to OpenRewrite?
In theory, I would, but I'm unsure if I will find the time right now.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status