spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.18k stars 40.68k forks source link

Add support for apache toolchains during spring-boot:repackage #34436

Closed InYourHead closed 1 year ago

InYourHead commented 1 year ago

I'm trying to build spring boot appplication using maven-toolchains-plugin, and i realized, that toolchains is supported, but not during repackge goal.

Example pom:

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example.service</groupId>
    <artifactId>example</artifactId>
    <version>0.0.1</version>
    <name>example</name>
    <description>Demo project for Spring Boot</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <java.version>17</java.version>
        <spring-boot-admin.version>3.0.0</spring-boot-admin.version>
        <spring-cloud.version>2022.0.0</spring-cloud.version>
        <spring.consul.version>4.0.1</spring.consul.version>
        <apache.commons.version>3.12.0</apache.commons.version>

    </properties>

    <dependencies>
        <dependency>
            <groupId>de.codecentric</groupId>
            <artifactId>spring-boot-admin-starter-server</artifactId>
            <version>${spring-boot-admin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-all</artifactId>
            <version>${spring.consul.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${apache.commons.version}</version>
        </dependency>

    </dependencies>

    <profiles>
        <profile>
            <id>local</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-toolchains-plugin</artifactId>
                        <version>3.1.0</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>toolchain</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <toolchains>
                                <jdk>
                                    <version>17</version>
                                </jdk>
                            </toolchains>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <release>${java.version}</release>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <compilerArgs>
                        <arg>--add-modules</arg>
                        <arg>java.base</arg>
                    </compilerArgs>
                    <compilerVersion>${java.version}</compilerVersion>
                    <encoding>${project.build.sourceEncoding}</encoding>
                    <fork>true</fork>
                    <meminitial>512m</meminitial>
                    <maxmem>1024m</maxmem>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

I'm using java 12 to run

mvn clean install  -P local -DskipTests -DskipITs -T2C

And I'm getting an error:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:3.0.2:repackage (repackage) on project example: Execution repackage of goal org.springframework.boot:spring-boot-maven-plugin:3.0.2:repackage failed: Unable to load the mojo 'repackage' in the plugin 'org.springframework.boot:spring-boot-maven-plugin:3.0.2' due to an API incompatibility: org.codehaus.plexus.component.repository.exception.ComponentLookupException: org/springframework/boot/maven/RepackageMojo has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 56.0

Is there any workaround to build spring boot application with toolchains?

wilkinsona commented 1 year ago

Duplicates #33940.

I don't think toolchains will help here. While a toolchain allows a plugin to fork a different JVM as needed, the plugin itself will still run in the main Maven JVM and Spring Boot 3.0's Maven plugin requires Java 17.

deepakab03 commented 1 year ago

If toolchains are enabled, there should be an option that makes the spring-boot plugin fork a JVM and run the repackage goal under the toolchain JVM version - otherwise how is the spring-boot plugin supporting toolchains in the true sense?

wilkinsona commented 1 year ago

How would that help? The Spring Boot plugin still has to be loaded in the main Maven JVM before it could fork a separate JVM.

jef5ez commented 1 year ago

How true is it that it really "has" to be in the main maven thread? I would second that it would be really nice to get a project out the spring initializer and be able to add this kind of toolchain plugin block and use the java version specified and have it actually build.

            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-toolchains-plugin</artifactId>
                <version>3.0.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>toolchain</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <toolchains>
                        <jdk>
                            <version>${java.version}</version>
                        </jdk>
                    </toolchains>
                </configuration>
            </plugin>

I see that there is at least this verify being called https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/java/org/springframework/boot/maven/RunIntegrationTests.java#L137 which this I assume uses this toolchain https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot-tools/spring-boot-maven-plugin/src/intTest/projects/run-toolchains/toolchains.xml but seems like that must not execute repackage. (For what it's worth I also get errors with spring-boot:run if maven is started with java 8)

philwebb commented 1 year ago

Our Maven plugin requires Java 17 and won't load on earlier versions of Java. I guess it might be technically possible for us to develop a small Java 8 compatible Maven plugin that forks the real plugin, but that's quite a lot of work and will add complexity to our own build which we don't want to do.