Both IDEA and Spring Tools launch Boot apps during development with customised tiered compilation and the verifier disabled to reduce startup time. We should do the same with spring-boot:run in Maven and bootRun in Gradle.

Comment From: ghost

@wilkinsona Can we get a reference to study for IDEA and Spring Tools about customising tiered compilation and the disabled verifier?

Comment From: wilkinsona

@dosdebug You can just launch an app using their Spring Boot support and take a look at the JVM options. I'm not sure if it's documented anywhere in either case. The relevant code in Spring IDE is here.

Comment From: ghost

@wilkinsona There will definitely be a better solution but can you please see and suggest if it's the right direction or where should I focus on.

https://github.com/dosdebug/spring-boot/commit/d712978571c79195ab5f0d0d396d4633848cb390

I never have tried contributing before but trying to see if I can really do it.

Comment From: wilkinsona

Thanks for taking a look at this, @dosdebug. I'm not sure we're quite ready to implement this yet as we have some design decisions to make. For example, we need to decide when the arguments should be applied (always, when the user doesn't specify anything, always unless they've been disabled, etc).

Comment From: ghost

@wilkinsona Okay sure. No worries. But thank you for your time.

Comment From: wilkinsona

This branch contains a proposal for the Gradle side of things.

By default -Xverify:none and -XX:TieredStopAtLevel=1 are added to the JVM args used by the BootRun task. This happens both when the user has configured some JVM args and when they have not. The addition of these JVM arguments can be disabled by setting a new fastLaunch property to false.

I originally explored an approach that would not need the fastLaunch property, but it got quite complex and difficult to understand, particularly when the application plugin's applicationDefaultJvmArgs property was taken into consideration. While what I've ended up with adds an extra property, I think that added complexity is outweighed by the behaviour being simpler and easier to document. It should also be possible to implement the same behaviour in the Maven plugin.

Flagging for team attention to see if we have agreement on the approach. I'm also not convinced by the name of the fastLaunch property so suggestions for a better name would be much appreciated.

Comment From: ghost

@wilkinsona How about just quick?

Comment From: wilkinsona

Thanks for the suggestion. Disabling the verifier has no benefit once all of the classes have been loaded and tuning the JIT to stop at an earlier compilation level actually slows things down for a long-running process. In other words, the settings really only reduce the initial startup time rather than making everything quick. As such, I think launch, start or something similar should appear in the name.

Comment From: wilkinsona

Inspired by the terminology used in IntelliJ IDEA, we're going to go with optimizedLaunch.

Comment From: wilkinsona

@dosdebug Would you like to update your proposal for Maven based on what I have done for Gradle but with the property being called optimizedLaunch?

Comment From: ghost

@wilkinsona Sure, I am going to give it a try and submit PR

Comment From: ghost

@wilkinsona Please review https://github.com/spring-projects/spring-boot/pull/16941 when you have time.

Comment From: wilkinsona

I've retitled this issue to focus on Gradle. #16941 will take care of the Maven side of things.

Comment From: yihtserns

Note to fellow users

When you have a transitive import/dependency missing from classpath e.g. because it's not actually used at runtime, and you're wondering why: 1. NoClassDefFoundError is thrown for that when you use the Spring Boot app via the built distribution/Docker, but 2. That same issue is not reproducible when running via bootRun

...that's because this change added -Xverify:none for #​2. If you want #​2 to behave as close as possible to #​1, do (for Gradle):

tasks.withType(org.springframework.boot.gradle.tasks.run.BootRun) {
    optimizedLaunch = false
}