23
23
import java .util .List ;
24
24
import java .util .function .Consumer ;
25
25
26
+ import org .jspecify .annotations .Nullable ;
27
+
26
28
import org .springframework .aot .hint .ExecutableMode ;
27
29
import org .springframework .aot .hint .RuntimeHints ;
28
30
import org .springframework .beans .BeanUtils ;
@@ -105,6 +107,8 @@ public class SpringBootContextLoader extends AbstractContextLoader implements Ao
105
107
private static final Consumer <SpringApplication > ALREADY_CONFIGURED = (springApplication ) -> {
106
108
};
107
109
110
+ private static final Object NONE = new Object ();
111
+
108
112
@ Override
109
113
public ApplicationContext loadContext (MergedContextConfiguration mergedConfig ) throws Exception {
110
114
return loadContext (mergedConfig , Mode .STANDARD , null , null );
@@ -123,8 +127,8 @@ public ApplicationContext loadContextForAotRuntime(MergedContextConfiguration me
123
127
}
124
128
125
129
private ApplicationContext loadContext (MergedContextConfiguration mergedConfig , Mode mode ,
126
- ApplicationContextInitializer <ConfigurableApplicationContext > initializer , RuntimeHints runtimeHints )
127
- throws Exception {
130
+ @ Nullable ApplicationContextInitializer <ConfigurableApplicationContext > initializer ,
131
+ @ Nullable RuntimeHints runtimeHints ) throws Exception {
128
132
assertHasClassesOrLocations (mergedConfig );
129
133
SpringBootTestAnnotation annotation = SpringBootTestAnnotation .get (mergedConfig );
130
134
String [] args = annotation .getArgs ();
@@ -153,7 +157,7 @@ private void assertHasClassesOrLocations(MergedContextConfiguration mergedConfig
153
157
+ SpringVersion .getVersion () + ")." );
154
158
}
155
159
156
- private Method getMainMethod (MergedContextConfiguration mergedConfig , UseMainMethod useMainMethod ) {
160
+ private @ Nullable Method getMainMethod (MergedContextConfiguration mergedConfig , UseMainMethod useMainMethod ) {
157
161
if (useMainMethod == UseMainMethod .NEVER ) {
158
162
return null ;
159
163
}
@@ -167,14 +171,16 @@ private Method getMainMethod(MergedContextConfiguration mergedConfig, UseMainMet
167
171
"Cannot use main method as no @SpringBootConfiguration-annotated class is available" );
168
172
Method mainMethod = findMainMethod (springBootConfiguration );
169
173
Assert .state (mainMethod != null || useMainMethod == UseMainMethod .WHEN_AVAILABLE ,
170
- () -> "Main method not found on '%s'" .formatted (springBootConfiguration .getName ()));
174
+ () -> "Main method not found on '%s'"
175
+ .formatted ((springBootConfiguration != null ) ? springBootConfiguration .getName () : null ));
171
176
return mainMethod ;
172
177
}
173
178
174
- private static Method findMainMethod (Class <?> type ) {
179
+ private static @ Nullable Method findMainMethod (@ Nullable Class <?> type ) {
175
180
Method mainMethod = (type != null ) ? ReflectionUtils .findMethod (type , "main" , String [].class ) : null ;
176
181
if (mainMethod == null && KotlinDetector .isKotlinPresent ()) {
177
182
try {
183
+ Assert .state (type != null , "'type' must not be null" );
178
184
Class <?> kotlinClass = ClassUtils .forName (type .getName () + "Kt" , type .getClassLoader ());
179
185
mainMethod = ReflectionUtils .findMethod (kotlinClass , "main" , String [].class );
180
186
}
@@ -285,7 +291,7 @@ protected SpringApplication getSpringApplication() {
285
291
* method if you need a custom environment.
286
292
* @return a {@link ConfigurableEnvironment} instance
287
293
*/
288
- protected ConfigurableEnvironment getEnvironment () {
294
+ protected @ Nullable ConfigurableEnvironment getEnvironment () {
289
295
return null ;
290
296
}
291
297
@@ -462,9 +468,9 @@ public void initialize(ConfigurableApplicationContext applicationContext) {
462
468
private static class ParentContextApplicationContextInitializer
463
469
implements ApplicationContextInitializer <ConfigurableApplicationContext > {
464
470
465
- private final ApplicationContext parent ;
471
+ private final @ Nullable ApplicationContext parent ;
466
472
467
- ParentContextApplicationContextInitializer (ApplicationContext parent ) {
473
+ ParentContextApplicationContextInitializer (@ Nullable ApplicationContext parent ) {
468
474
this .parent = parent ;
469
475
}
470
476
@@ -507,15 +513,16 @@ private static class ContextLoaderHook implements SpringApplicationHook {
507
513
508
514
private final Mode mode ;
509
515
510
- private final ApplicationContextInitializer <ConfigurableApplicationContext > initializer ;
516
+ private final @ Nullable ApplicationContextInitializer <ConfigurableApplicationContext > initializer ;
511
517
512
518
private final Consumer <SpringApplication > configurer ;
513
519
514
520
private final List <ApplicationContext > contexts = Collections .synchronizedList (new ArrayList <>());
515
521
516
522
private final List <ApplicationContext > failedContexts = Collections .synchronizedList (new ArrayList <>());
517
523
518
- ContextLoaderHook (Mode mode , ApplicationContextInitializer <ConfigurableApplicationContext > initializer ,
524
+ ContextLoaderHook (Mode mode ,
525
+ @ Nullable ApplicationContextInitializer <ConfigurableApplicationContext > initializer ,
519
526
Consumer <SpringApplication > configurer ) {
520
527
this .mode = mode ;
521
528
this .initializer = initializer ;
@@ -530,6 +537,7 @@ public SpringApplicationRunListener getRunListener(SpringApplication application
530
537
public void starting (ConfigurableBootstrapContext bootstrapContext ) {
531
538
ContextLoaderHook .this .configurer .accept (application );
532
539
if (ContextLoaderHook .this .mode == Mode .AOT_RUNTIME ) {
540
+ Assert .state (ContextLoaderHook .this .initializer != null , "'initializer' must not be null" );
533
541
application .addInitializers (
534
542
(AotApplicationContextInitializer <?>) ContextLoaderHook .this .initializer ::initialize );
535
543
}
@@ -544,24 +552,24 @@ public void contextLoaded(ConfigurableApplicationContext context) {
544
552
}
545
553
546
554
@ Override
547
- public void failed (ConfigurableApplicationContext context , Throwable exception ) {
555
+ public void failed (@ Nullable ConfigurableApplicationContext context , Throwable exception ) {
548
556
ContextLoaderHook .this .failedContexts .add (context );
549
557
}
550
558
551
559
};
552
560
}
553
561
554
- private < T > ApplicationContext runMain (Runnable action ) throws Exception {
562
+ private ApplicationContext runMain (Runnable action ) throws Exception {
555
563
return run (() -> {
556
564
action .run ();
557
- return null ;
565
+ return NONE ;
558
566
});
559
567
}
560
568
561
- private ApplicationContext run (ThrowingSupplier <ConfigurableApplicationContext > action ) throws Exception {
569
+ private ApplicationContext run (ThrowingSupplier <? > action ) throws Exception {
562
570
try {
563
- ConfigurableApplicationContext context = SpringApplication .withHook (this , action );
564
- if (context != null ) {
571
+ Object result = SpringApplication .withHook (this , action );
572
+ if (result instanceof ApplicationContext context ) {
565
573
return context ;
566
574
}
567
575
}
0 commit comments