How to have multiple versions of @SpringBootApplication main classes in multi release jar?

Viewed 85

I am having 2 different versions of spring config pertaining to 2 different versions of java i.e java 8 and java 11

the project structure is something like :

project structure

pom.xml :

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-toolchains-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <toolchains>
                    <jdk>
                        <version>zulu-11</version>
                    </jdk>
                </toolchains>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>toolchain</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.1</version>
            <executions>
                <execution>
                    <id>default-compile</id>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <release>8</release>
                    </configuration>
                </execution>
                <execution>
                    <id>compile-java-11</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                    <configuration>
                        <release>11</release>
                        <compileSourceRoots>
                            <compileSourceRoot>${project.basedir}/src/main/java11</compileSourceRoot>
                        </compileSourceRoots>
                        <multiReleaseOutput>true</multiReleaseOutput>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.2.0</version>
            <configuration>
                <archive>
                    <manifestEntries>
                        <Multi-Release>true</Multi-Release>
                    </manifestEntries>
                </archive>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

but upon building the project, the build fails with following reason

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.981 s
[INFO] Finished at: 2021-10-01T21:56:03+05:30
[INFO] Final Memory: 23M/293M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.5.5:repackage (repackage) on project demo: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:2.5.5:repackage failed: Unab
le to find a single main class from the following candidates [com.example.demo.DemoApplication, META-INF.versions.11.com.example.demo.DemoApplication] -> [Help 1]
[ERROR]

So, is there any way to use two classes without getting this build failure?

Also, I cannot use profiles and mention class to be used in a specific profile.

1 Answers

You can use the start-class property in your pom.xml to configure the class that's used to start your application.

<properties>
    <start-class>com.example.demo.DemoApplication</start-class>
</properties>

When you run your application on Java 11 using java -jar, the DemoApplication variant in META-INF/versions/11 should be used automatically.

Related