Skip to content

Commit 5101ac8

Browse files
Merge branch 'fix-android-detection' into 'dev'
NativeLibraryLoader: always fall back to Android if not macOS/Windows. See merge request objectbox/objectbox-java!18
2 parents dcb4b7a + 77a2b0b commit 5101ac8

File tree

1 file changed

+44
-27
lines changed

1 file changed

+44
-27
lines changed

objectbox-java/src/main/java/io/objectbox/internal/NativeLibraryLoader.java

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -42,52 +42,70 @@ public class NativeLibraryLoader {
4242
static {
4343
String libname = OBJECTBOX_JNI;
4444
String filename = libname + ".so";
45-
boolean isLinux = false;
45+
46+
final String vendor = System.getProperty("java.vendor");
47+
final String osName = System.getProperty("os.name").toLowerCase();
48+
final String sunArch = System.getProperty("sun.arch.data.model");
49+
50+
// Some Android devices are detected as neither Android or Linux below,
51+
// so assume Linux by default to always fallback to Android
52+
boolean isLinux = true;
4653
// For Android, os.name is also "Linux", so we need an extra check
4754
// Is not completely reliable (e.g. Vivo devices), see workaround on load failure
4855
// Note: can not use check for Android classes as testing frameworks (Robolectric)
4956
// may provide them on non-Android devices
50-
boolean android = System.getProperty("java.vendor").contains("Android");
57+
final boolean android = vendor.contains("Android");
5158
if (!android) {
52-
String osName = System.getProperty("os.name").toLowerCase();
53-
String sunArch = System.getProperty("sun.arch.data.model");
5459
String cpuArchPostfix = "32".equals(sunArch) ? "-x86" : "-x64";
5560
if (osName.contains("windows")) {
61+
isLinux = false;
5662
libname += "-windows" + cpuArchPostfix;
5763
filename = libname + ".dll";
5864
checkUnpackLib(filename);
5965
} else if (osName.contains("linux")) {
60-
isLinux = true;
6166
libname += "-linux" + cpuArchPostfix;
6267
filename = "lib" + libname + ".so";
6368
checkUnpackLib(filename);
6469
} else if (osName.contains("mac")) {
70+
isLinux = false;
6571
libname += "-macos" + cpuArchPostfix;
6672
filename = "lib" + libname + ".dylib";
6773
checkUnpackLib(filename);
6874
}
6975
}
70-
File file = new File(filename);
71-
if (file.exists()) {
72-
System.load(file.getAbsolutePath());
73-
} else {
74-
if (!android) {
75-
System.err.println("File not available: " + file.getAbsolutePath());
76-
}
77-
try {
78-
if (!android || !loadLibraryAndroid(libname)) {
79-
System.loadLibrary(libname);
80-
}
81-
} catch (UnsatisfiedLinkError e) {
82-
if (!android && isLinux) {
83-
// maybe is Android, but check failed: try loading Android lib
84-
if (!loadLibraryAndroid(OBJECTBOX_JNI)) {
85-
System.loadLibrary(OBJECTBOX_JNI);
76+
try {
77+
File file = new File(filename);
78+
if (file.exists()) {
79+
System.load(file.getAbsolutePath());
80+
} else {
81+
try {
82+
if (android) {
83+
boolean success = loadLibraryAndroid();
84+
if (!success) {
85+
System.loadLibrary(libname);
86+
}
87+
} else {
88+
System.err.println("File not available: " + file.getAbsolutePath());
89+
System.loadLibrary(libname);
90+
}
91+
} catch (UnsatisfiedLinkError e) {
92+
if (!android && isLinux) {
93+
// maybe is Android, but check failed: try loading Android lib
94+
boolean success = loadLibraryAndroid();
95+
if (!success) {
96+
System.loadLibrary(OBJECTBOX_JNI);
97+
}
98+
} else {
99+
throw e;
86100
}
87-
} else {
88-
throw e;
89101
}
90102
}
103+
} catch (UnsatisfiedLinkError e) {
104+
String message = String.format(
105+
"Loading ObjectBox native library failed: vendor=%s,os=%s,arch=%s,android=%s,linux=%s",
106+
vendor, osName, sunArch, android, isLinux
107+
);
108+
throw new LinkageError(message, e); // UnsatisfiedLinkError does not allow a cause; use its super class
91109
}
92110
}
93111

@@ -124,8 +142,7 @@ private static void checkUnpackLib(String filename) {
124142
}
125143
}
126144

127-
@SuppressWarnings("BooleanMethodIsAlwaysInverted") // more readable
128-
private static boolean loadLibraryAndroid(String libname) {
145+
private static boolean loadLibraryAndroid() {
129146
if (BoxStore.context == null) {
130147
return false;
131148
}
@@ -137,11 +154,11 @@ private static boolean loadLibraryAndroid(String libname) {
137154
// use default ReLinker
138155
Class<?> relinker = Class.forName("com.getkeepsafe.relinker.ReLinker");
139156
Method loadLibrary = relinker.getMethod("loadLibrary", context, String.class, String.class);
140-
loadLibrary.invoke(null, BoxStore.context, libname, BoxStore.JNI_VERSION);
157+
loadLibrary.invoke(null, BoxStore.context, OBJECTBOX_JNI, BoxStore.JNI_VERSION);
141158
} else {
142159
// use custom ReLinkerInstance
143160
Method loadLibrary = BoxStore.relinker.getClass().getMethod("loadLibrary", context, String.class, String.class);
144-
loadLibrary.invoke(BoxStore.relinker, BoxStore.context, libname, BoxStore.JNI_VERSION);
161+
loadLibrary.invoke(BoxStore.relinker, BoxStore.context, OBJECTBOX_JNI, BoxStore.JNI_VERSION);
145162
}
146163
} catch (NoSuchMethodException e) {
147164
return false;

0 commit comments

Comments
 (0)