Skip to content

Commit 7c7c9b9

Browse files
cesar1000akarnokd
authored andcommitted
Fix resolveAndroidApiVersion when running under Robolectric (ReactiveX#4912)
PlatformDependent.resolveAndroidApiVersion() tries to determine the Android SDK version by reading the android.os.Build$VERSION#SDK_INT field. When running under Robolectric, the class will be found (since Robolectric bundles an original android.jar). However, the method is using the system class loader for loading it (instead of the Robolectric instrumenting class loader), which will not instrument the class to run in the JVM. As a result, static initialization of the class fails with an UnsatisfiedLinkError when calling SystemProperties.get(), which calls native method native_get. I fixed by using the default class loader instead. This would only make a difference in the extremely rare case that the Android application installs a class loader that's not capable of finding Android classes. I tested that this behaves as expected on a device, fixes the issue with Robolectric, and detects it's not Android otherwise (as proven by the unit test).
1 parent 57a9c09 commit 7c7c9b9

File tree

2 files changed

+10
-20
lines changed

2 files changed

+10
-20
lines changed

src/main/java/rx/internal/util/PlatformDependent.java

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
*/
1616
package rx.internal.util;
1717

18-
import java.security.AccessController;
19-
import java.security.PrivilegedAction;
20-
2118
/**
2219
* Allow platform dependent logic such as checks for Android.
2320
*
@@ -67,7 +64,7 @@ public static int getAndroidApiVersion() {
6764
private static int resolveAndroidApiVersion() {
6865
try {
6966
return (Integer) Class
70-
.forName("android.os.Build$VERSION", true, getSystemClassLoader())
67+
.forName("android.os.Build$VERSION")
7168
.getField("SDK_INT")
7269
.get(null);
7370
} catch (Exception e) { // NOPMD
@@ -76,20 +73,4 @@ private static int resolveAndroidApiVersion() {
7673
return ANDROID_API_VERSION_IS_NOT_ANDROID;
7774
}
7875
}
79-
80-
/**
81-
* Return the system {@link ClassLoader}.
82-
*/
83-
static ClassLoader getSystemClassLoader() {
84-
if (System.getSecurityManager() == null) {
85-
return ClassLoader.getSystemClassLoader();
86-
} else {
87-
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
88-
@Override
89-
public ClassLoader run() {
90-
return ClassLoader.getSystemClassLoader();
91-
}
92-
});
93-
}
94-
}
9576
}

src/test/java/rx/internal/util/PlatformDependentTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,18 @@
1919

2020
import rx.TestUtil;
2121

22+
import static org.junit.Assert.assertEquals;
23+
import static org.junit.Assert.assertFalse;
24+
2225
public class PlatformDependentTest {
2326
@Test
2427
public void constructorShouldBePrivate() {
2528
TestUtil.checkUtilityClass(PlatformDependent.class);
2629
}
30+
31+
@Test
32+
public void platformShouldNotBeAndroid() {
33+
assertFalse(PlatformDependent.isAndroid());
34+
assertEquals(0, PlatformDependent.getAndroidApiVersion());
35+
}
2736
}

0 commit comments

Comments
 (0)