@@ -71,6 +71,12 @@ public class ServiceHelper extends AbstractContextual {
7171 /** Classes to instantiate as services. */
7272 private final List <Class <? extends Service >> serviceClasses ;
7373
74+ /**
75+ * Whether service loading will fail fast when there is an error instantiating
76+ * a required service.
77+ */
78+ private final boolean strict ;
79+
7480 /**
7581 * Creates a new service helper for discovering and instantiating services.
7682 *
@@ -89,6 +95,21 @@ public ServiceHelper(final Context context) {
8995 */
9096 public ServiceHelper (final Context context ,
9197 final Collection <Class <? extends Service >> serviceClasses )
98+ {
99+ this (context , serviceClasses , true );
100+ }
101+
102+ /**
103+ * Creates a new service helper for discovering and instantiating services.
104+ *
105+ * @param context The application context to which services should be added.
106+ * @param serviceClasses The service classes to instantiate.
107+ * @param strict Whether service loading will fail fast when there is an error
108+ * instantiating a required service.
109+ */
110+ public ServiceHelper (final Context context ,
111+ final Collection <Class <? extends Service >> serviceClasses ,
112+ final boolean strict )
92113 {
93114 setContext (context );
94115 log = context .getService (LogService .class );
@@ -108,6 +129,7 @@ public ServiceHelper(final Context context,
108129 // load only the services that were explicitly specified
109130 this .serviceClasses .addAll (serviceClasses );
110131 }
132+ this .strict = strict ;
111133 }
112134
113135 // -- ServiceHelper methods --
@@ -207,15 +229,19 @@ private <S extends Service> S loadService(final Class<S> c,
207229 @ SuppressWarnings ("unchecked" )
208230 final S result = (S ) createExactService (serviceClass , required );
209231 if (required && result == null ) {
210- throw new IllegalArgumentException ();
232+ final String error = "No match: " + serviceClass .getName ();
233+ if (strict ) throw new IllegalArgumentException (error );
234+ log .error (error );
211235 }
212236 return result ;
213237 }
214238 }
215239
216240 if (required && c .isInterface ()) {
217- throw new IllegalArgumentException ("No compatible service: " +
218- c .getName ());
241+ final String error = "No compatible service: " + c .getName ();
242+ if (strict ) throw new IllegalArgumentException (error );
243+ log .error (error );
244+ return null ;
219245 }
220246
221247 return createExactService (c , required );
@@ -249,9 +275,11 @@ private <S extends Service> S createExactService(final Class<S> c,
249275 }
250276 catch (final Throwable t ) {
251277 if (required ) {
252- throw new IllegalArgumentException ("Invalid service: " + name , t );
278+ final String error = "Invalid service: " + name ;
279+ if (strict ) throw new IllegalArgumentException (error , t );
280+ log .error (error , t );
253281 }
254- if (log .isDebug ()) {
282+ else if (log .isDebug ()) {
255283 // when in debug mode, give full stack trace of invalid services
256284 log .debug ("Invalid service: " + name , t );
257285 }
@@ -290,8 +318,11 @@ private <S extends Service> S createServiceRecursively(final Class<S> c)
290318 continue ;
291319 }
292320 if (!Service .class .isAssignableFrom (type )) {
293- throw new IllegalArgumentException ("Invalid parameter: " +
294- f .getDeclaringClass ().getName () + "#" + f .getName ());
321+ final String error = "Invalid parameter: " +
322+ f .getDeclaringClass ().getName () + "#" + f .getName ();
323+ if (strict ) throw new IllegalArgumentException (error );
324+ log .error (error );
325+ continue ;
295326 }
296327 @ SuppressWarnings ("unchecked" )
297328 final Class <? extends Service > serviceType =
0 commit comments