Prevent main method to continue once the AOT context has been optimized
This commit makes sure that processing of the main method upon completion of SpringApplication#run. Previously, any instructions in the user's main method were invoked, which is not suitable to build-time processing. Closes gh-31219
This commit is contained in:
parent
d044eaf69d
commit
44a8e91b9e
|
|
@ -39,8 +39,21 @@ class AotProcessingHook implements Hook {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postRun(SpringApplication application, ConfigurableApplicationContext context) {
|
||||
throw new MainMethodSilentExitException();
|
||||
}
|
||||
|
||||
GenericApplicationContext getApplicationContext() {
|
||||
return this.context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal exception used to prevent main method to continue once
|
||||
* {@code SpringApplication#run} completes.
|
||||
*/
|
||||
static class MainMethodSilentExitException extends RuntimeException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.boot;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
|
@ -34,6 +35,7 @@ import org.springframework.aot.hint.ExecutableMode;
|
|||
import org.springframework.aot.hint.RuntimeHints;
|
||||
import org.springframework.aot.hint.TypeReference;
|
||||
import org.springframework.aot.nativex.FileNativeConfigurationWriter;
|
||||
import org.springframework.boot.AotProcessingHook.MainMethodSilentExitException;
|
||||
import org.springframework.context.aot.ApplicationContextAotGenerator;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.javapoet.ClassName;
|
||||
|
|
@ -124,6 +126,13 @@ public class AotProcessor {
|
|||
try {
|
||||
this.application.getMethod("main", String[].class).invoke(null, new Object[] { this.applicationArgs });
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
Throwable targetException = ex.getTargetException();
|
||||
if (!(targetException instanceof MainMethodSilentExitException)) {
|
||||
throw (targetException instanceof RuntimeException runtimeEx) ? runtimeEx
|
||||
: new RuntimeException(targetException);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ class AotProcessorTests {
|
|||
@BeforeEach
|
||||
void setup() {
|
||||
SampleApplication.argsHolder = null;
|
||||
SampleApplication.postRunInvoked = false;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -50,6 +51,7 @@ class AotProcessorTests {
|
|||
directory.resolve("resource"), directory.resolve("class"), "com.example", "example");
|
||||
processor.process();
|
||||
assertThat(SampleApplication.argsHolder).isEqualTo(arguments);
|
||||
assertThat(SampleApplication.postRunInvoked).isFalse();
|
||||
assertThat(directory).satisfies(hasGeneratedAssetsForSampleApplication());
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +71,7 @@ class AotProcessorTests {
|
|||
directory.resolve("class").toString(), "com.example", "example", "1", "2" };
|
||||
AotProcessor.main(mainArguments);
|
||||
assertThat(SampleApplication.argsHolder).containsExactly("1", "2");
|
||||
assertThat(SampleApplication.postRunInvoked).isFalse();
|
||||
assertThat(directory).satisfies(hasGeneratedAssetsForSampleApplication());
|
||||
}
|
||||
|
||||
|
|
@ -125,9 +128,12 @@ class AotProcessorTests {
|
|||
|
||||
public static String[] argsHolder;
|
||||
|
||||
public static boolean postRunInvoked;
|
||||
|
||||
public static void main(String[] args) {
|
||||
argsHolder = args;
|
||||
SpringApplication.run(SampleApplication.class, args);
|
||||
postRunInvoked = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue