@@ -105,7 +105,7 @@ public void reset() {
105
105
public RxJavaErrorHandler getErrorHandler () {
106
106
if (errorHandler .get () == null ) {
107
107
// check for an implementation from System.getProperty first
108
- Object impl = getPluginImplementationViaProperty (RxJavaErrorHandler .class , System . getProperties ());
108
+ Object impl = getPluginImplementationViaProperty (RxJavaErrorHandler .class , getSystemPropertiesSafe ());
109
109
if (impl == null ) {
110
110
// nothing set via properties so initialize with default
111
111
errorHandler .compareAndSet (null , DEFAULT_ERROR_HANDLER );
@@ -147,7 +147,7 @@ public void registerErrorHandler(RxJavaErrorHandler impl) {
147
147
public RxJavaObservableExecutionHook getObservableExecutionHook () {
148
148
if (observableExecutionHook .get () == null ) {
149
149
// check for an implementation from System.getProperty first
150
- Object impl = getPluginImplementationViaProperty (RxJavaObservableExecutionHook .class , System . getProperties ());
150
+ Object impl = getPluginImplementationViaProperty (RxJavaObservableExecutionHook .class , getSystemPropertiesSafe ());
151
151
if (impl == null ) {
152
152
// nothing set via properties so initialize with default
153
153
observableExecutionHook .compareAndSet (null , RxJavaObservableExecutionHookDefault .getInstance ());
@@ -189,7 +189,7 @@ public void registerObservableExecutionHook(RxJavaObservableExecutionHook impl)
189
189
public RxJavaSingleExecutionHook getSingleExecutionHook () {
190
190
if (singleExecutionHook .get () == null ) {
191
191
// check for an implementation from System.getProperty first
192
- Object impl = getPluginImplementationViaProperty (RxJavaSingleExecutionHook .class , System . getProperties ());
192
+ Object impl = getPluginImplementationViaProperty (RxJavaSingleExecutionHook .class , getSystemPropertiesSafe ());
193
193
if (impl == null ) {
194
194
// nothing set via properties so initialize with default
195
195
singleExecutionHook .compareAndSet (null , RxJavaSingleExecutionHookDefault .getInstance ());
@@ -232,7 +232,7 @@ public void registerSingleExecutionHook(RxJavaSingleExecutionHook impl) {
232
232
public RxJavaCompletableExecutionHook getCompletableExecutionHook () {
233
233
if (completableExecutionHook .get () == null ) {
234
234
// check for an implementation from System.getProperty first
235
- Object impl = getPluginImplementationViaProperty (RxJavaCompletableExecutionHook .class , System . getProperties ());
235
+ Object impl = getPluginImplementationViaProperty (RxJavaCompletableExecutionHook .class , getSystemPropertiesSafe ());
236
236
if (impl == null ) {
237
237
// nothing set via properties so initialize with default
238
238
completableExecutionHook .compareAndSet (null , new RxJavaCompletableExecutionHook () { });
@@ -262,6 +262,19 @@ public void registerCompletableExecutionHook(RxJavaCompletableExecutionHook impl
262
262
}
263
263
}
264
264
265
+ /**
266
+ * A security manager may prevent accessing the System properties entirely,
267
+ * therefore, the SecurityException is turned into an empty properties.
268
+ * @return the Properties to use for looking up settings
269
+ */
270
+ /* test */ static Properties getSystemPropertiesSafe () {
271
+ try {
272
+ return System .getProperties ();
273
+ } catch (SecurityException ex ) {
274
+ return new Properties ();
275
+ }
276
+ }
277
+
265
278
/* test */ static Object getPluginImplementationViaProperty (Class <?> pluginClass , Properties propsIn ) {
266
279
// Make a defensive clone because traversal may fail with ConcurrentModificationException
267
280
// if the properties get changed by something outside RxJava.
@@ -284,25 +297,32 @@ public void registerCompletableExecutionHook(RxJavaCompletableExecutionHook impl
284
297
String classSuffix = ".class" ;
285
298
String implSuffix = ".impl" ;
286
299
287
- for (Map .Entry <Object , Object > e : props .entrySet ()) {
288
- String key = e .getKey ().toString ();
289
- if (key .startsWith (pluginPrefix ) && key .endsWith (classSuffix )) {
290
- String value = e .getValue ().toString ();
300
+ try {
301
+ for (Map .Entry <Object , Object > e : props .entrySet ()) {
302
+ String key = e .getKey ().toString ();
303
+ if (key .startsWith (pluginPrefix ) && key .endsWith (classSuffix )) {
304
+ String value = e .getValue ().toString ();
305
+
306
+ if (classSimpleName .equals (value )) {
307
+ String index = key .substring (0 , key .length () - classSuffix .length ()).substring (pluginPrefix .length ());
291
308
292
- if (classSimpleName .equals (value )) {
293
- String index = key .substring (0 , key .length () - classSuffix .length ()).substring (pluginPrefix .length ());
309
+ String implKey = pluginPrefix + index + implSuffix ;
294
310
295
- String implKey = pluginPrefix + index + implSuffix ;
311
+ implementingClass = props . getProperty ( implKey ) ;
296
312
297
- implementingClass = props .getProperty (implKey );
313
+ if (implementingClass == null ) {
314
+ throw new IllegalStateException ("Implementing class declaration for " + classSimpleName + " missing: " + implKey );
315
+ }
298
316
299
- if (implementingClass == null ) {
300
- throw new IllegalStateException ("Implementing class declaration for " + classSimpleName + " missing: " + implKey );
317
+ break ;
301
318
}
302
-
303
- break ;
304
319
}
305
320
}
321
+ } catch (SecurityException ex ) {
322
+ // https://github.com/ReactiveX/RxJava/issues/5819
323
+ // We don't seem to have access to all properties.
324
+ // At least print the exception to the console.
325
+ ex .printStackTrace ();
306
326
}
307
327
}
308
328
@@ -339,7 +359,7 @@ public void registerCompletableExecutionHook(RxJavaCompletableExecutionHook impl
339
359
public RxJavaSchedulersHook getSchedulersHook () {
340
360
if (schedulersHook .get () == null ) {
341
361
// check for an implementation from System.getProperty first
342
- Object impl = getPluginImplementationViaProperty (RxJavaSchedulersHook .class , System . getProperties ());
362
+ Object impl = getPluginImplementationViaProperty (RxJavaSchedulersHook .class , getSystemPropertiesSafe ());
343
363
if (impl == null ) {
344
364
// nothing set via properties so initialize with default
345
365
schedulersHook .compareAndSet (null , RxJavaSchedulersHook .getDefaultInstance ());
0 commit comments