If you create an executable jar or war, you used to be able to do this via the Spring Boot Gradle or Maven plugins, and it would work with no problem. We have recently upgraded to Spring Boot 2.2.2 (from 1.4) and have found that unless you add the spring-boot-loader to the classpath, you get the following behaviour:

Process goes into a loop, consuming 100% cpu, and eventually gets a stack overflow. Looking at the output from this, you see that it is looping as below:

| *** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at JPLISAgent.c line: 844
Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
    at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:58)
 Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
    at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:58)
    ... 8 more
 Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:51)
    at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:58)
    ... 16 more

Comment From: wilkinsona

It looks like the launcher is calling itself rather than the application's own main method. That would suggest that the Start-Class in the manifest is wrong. Can you please share a small sample that reproduces the problem?

Comment From: ghost

Thanks for getting back to me so quickly, I'll try and create an example that replicates it.

Comment From: ghost

I've created a github project here that replicates the issue (https://github.com/paulnuk/springbootissue19577)

In order to replicate, do a clean and package, then cd to the target directory and do:

java -jar demo-0.0.1-SNAPSHOT-exec.jar

Comment From: ghost

Update to this - it seems that it is indeed trying to call itself, and can be fixed by specifying the main class of the Spring Boot Application instead on the plugin. The plugin probably needs some defensive code in it to make sure it doesn't call itself.

           <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>

                            <classifier>exec</classifier>
                            <mainClass>com.example.demo.DemoApplication</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

Comment From: wilkinsona

Thanks for the sample. Unfortunately, it doesn't reproduce the problem for me:

$ java -jar target/demo-0.0.1-SNAPSHOT.jar 

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.2.RELEASE)

2020-01-08 15:32:02.026  INFO 93728 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT on Andys-MacBook-Pro.local with PID 93728 (/Users/awilkinson/dev/temp/springbootissue19577/target/demo-0.0.1-SNAPSHOT.jar started by awilkinson in /Users/awilkinson/dev/temp/springbootissue19577)
2020-01-08 15:32:02.029  INFO 93728 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2020-01-08 15:32:02.823  INFO 93728 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2020-01-08 15:32:02.831  INFO 93728 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2020-01-08 15:32:02.831  INFO 93728 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.29]
2020-01-08 15:32:02.875  INFO 93728 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-01-08 15:32:02.875  INFO 93728 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 802 ms
2020-01-08 15:32:03.000  INFO 93728 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-01-08 15:32:03.150  INFO 93728 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2020-01-08 15:32:03.153  INFO 93728 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.488 seconds (JVM running for 1.871)

Can you please update it with the changes that are required to reproduce the problem?

Comment From: ghost

You need to run the repackaged jar, not the original (sorry, I edited my original instructions after the first post)

i.e.

java -jar target/demo-0.0.1-SNAPSHOT-exec.jar

not

java -jar target/demo-0.0.1-SNAPSHOT.jar

Comment From: wilkinsona

Thanks. The root cause is that the jar is being repackaged twice. Once to creating demo-0.0.1-SNAPSHOT.jar and then again creating demo-0.0.1-SNAPSHOT-exec.jar. This results in a Start-Class in the exec jar that points to the launcher and the stack overflow results. This is being tracked by https://github.com/spring-projects/spring-boot/issues/16828.

You probably don't want to repackage the jar twice. You can avoid that by specifying the <id> when configuring the execution of the repackage goal:

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                        <configuration>
                            <classifier>exec</classifier>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

This will customize the execution inherited from spring-boot-starter-parent rather than creating another one.

Comment From: snicoll

For completeness, this is also documented in the 2.1 release notes.