@@ -55,6 +55,8 @@ public class BootContext {
5555
5656  private  final  Set <String > includeModules  = new  LinkedHashSet <>();
5757
58+   private  boolean  ignoreMissingModuleDependencies ;
59+ 
5860  /** 
5961   * Create a BootContext to ultimately load and return a new BeanContext. 
6062   * 
@@ -115,6 +117,7 @@ public BootContext withNoShutdownHook() {
115117   *     try (BeanContext context = new BootContext() 
116118   *       .withBeans(mockEmailService) 
117119   *       .withModules("coffee") 
120+    *       .withIgnoreMissingModuleDependencies() 
118121   *       .load()) { 
119122   * 
120123   *       // built with test doubles injected ... 
@@ -127,7 +130,6 @@ public BootContext withNoShutdownHook() {
127130   * 
128131   * }</pre> 
129132   * 
130-    * 
131133   * @param modules The names of modules that we want to include in dependency injection. 
132134   * @return This BootContext 
133135   */ 
@@ -136,6 +138,15 @@ public BootContext withModules(String... modules) {
136138    return  this ;
137139  }
138140
141+   /** 
142+    * Set this when building a BeanContext (typically for testing) and supplied beans replace module dependencies. 
143+    * This means we don't need the usual module dependencies as supplied beans are used instead. 
144+    */ 
145+   public  BootContext  withIgnoreMissingModuleDependencies () {
146+     this .ignoreMissingModuleDependencies  = true ;
147+     return  this ;
148+   }
149+ 
139150  /** 
140151   * Supply a bean to the context that will be used instead of any similar bean in the context. 
141152   * <p> 
@@ -180,7 +191,7 @@ public BootContext withBeans(Object... beans) {
180191  public  BeanContext  load () {
181192
182193    // sort factories by dependsOn 
183-     FactoryOrder  factoryOrder  = new  FactoryOrder (includeModules , !suppliedBeans .isEmpty ());
194+     FactoryOrder  factoryOrder  = new  FactoryOrder (includeModules , !suppliedBeans .isEmpty (),  ignoreMissingModuleDependencies );
184195    ServiceLoader .load (BeanContextFactory .class ).forEach (factoryOrder ::add );
185196
186197    Set <String > moduleNames  = factoryOrder .orderFactories ();
@@ -308,16 +319,18 @@ static class FactoryOrder {
308319
309320    private  final  Set <String > includeModules ;
310321    private  final  boolean  suppliedBeans ;
322+     private  final  boolean  ignoreMissingModuleDependencies ;
311323
312324    private  final  Set <String > moduleNames  = new  LinkedHashSet <>();
313325    private  final  List <BeanContextFactory > factories  = new  ArrayList <>();
314326    private  final  List <FactoryState > queue  = new  ArrayList <>();
315327
316-     private  final  Map <String ,FactoryList > providesMap  = new  HashMap <>();
328+     private  final  Map <String ,  FactoryList > providesMap  = new  HashMap <>();
317329
318-     FactoryOrder (Set <String > includeModules , boolean  suppliedBeans ) {
330+     FactoryOrder (Set <String > includeModules , boolean  suppliedBeans ,  boolean   ignoreMissingModuleDependencies ) {
319331      this .includeModules  = includeModules ;
320332      this .suppliedBeans  = suppliedBeans ;
333+       this .ignoreMissingModuleDependencies  = ignoreMissingModuleDependencies ;
321334    }
322335
323336    void  add (BeanContextFactory  factory ) {
@@ -384,25 +397,26 @@ private void processQueue() {
384397        count  = processQueuedFactories ();
385398      } while  (count  > 0 );
386399
387-       if  (suppliedBeans ) {
400+       if  (suppliedBeans  ||  ignoreMissingModuleDependencies ) {
388401        // just push everything left assuming supplied beans 
389402        // will satisfy the required dependencies 
390403        for  (FactoryState  factoryState  : queue ) {
391404          push (factoryState );
392405        }
393406
394-       } else    if  (!queue .isEmpty ()) {
407+       } else  if  (!queue .isEmpty ()) {
395408        StringBuilder  sb  = new  StringBuilder ();
396409        for  (FactoryState  factory  : queue ) {
397-           sb .append ("module  " ).append (factory .getName ()).append (" has unsatisfied dependencies -  " );
410+           sb .append ("Module [ " ).append (factory .getName ()).append ("]  has unsatisfied dependencies on modules: " );
398411          for  (String  depModuleName  : factory .getDependsOn ()) {
399-             boolean   ok  =  moduleNames .contains (depModuleName ); 
400-             String   result  = ( ok ) ?  "ok"  :  "UNSATISFIED" ;
401-             sb . append ( String . format ( "depends on %s - %s" ,  depModuleName ,  result )); 
412+             if  (! moduleNames .contains (depModuleName )) { 
413+                sb . append ( String . format ( " [%s]" ,  depModuleName )) ;
414+             } 
402415          }
403416        }
404417
405-         sb .append ("- Modules loaded ok " ).append (moduleNames );
418+         sb .append (". Modules that were loaded ok are:" ).append (moduleNames );
419+         sb .append (". Consider using BootContext.withIgnoreMissingModuleDependencies() or BootContext.withSuppliedBeans(...)" );
406420        throw  new  IllegalStateException (sb .toString ());
407421      }
408422    }
0 commit comments