Skip to content

Commit 34af3ae

Browse files
committed
Merge remote-tracking branch 'origin/102-arm-integ-tests' into dev
2 parents 06eb86a + fcba5b2 commit 34af3ae

File tree

1 file changed

+68
-22
lines changed

1 file changed

+68
-22
lines changed

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

Lines changed: 68 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@
1616

1717
package io.objectbox.internal;
1818

19+
import io.objectbox.BoxStore;
1920
import org.greenrobot.essentials.io.IoUtils;
2021

22+
import javax.annotation.Nullable;
2123
import java.io.BufferedInputStream;
2224
import java.io.BufferedOutputStream;
25+
import java.io.BufferedReader;
2326
import java.io.File;
2427
import java.io.FileOutputStream;
2528
import java.io.IOException;
2629
import java.io.InputStream;
30+
import java.io.InputStreamReader;
2731
import java.io.OutputStream;
2832
import java.lang.reflect.InvocationTargetException;
2933
import java.lang.reflect.Method;
3034
import java.net.URL;
3135
import java.net.URLConnection;
3236

33-
import io.objectbox.BoxStore;
34-
3537
/**
3638
* Separate class, so we can mock BoxStore.
3739
*/
@@ -103,13 +105,21 @@ public class NativeLibraryLoader {
103105
String osArch = System.getProperty("os.arch");
104106
String sunArch = System.getProperty("sun.arch.data.model");
105107
String message = String.format(
106-
"Loading ObjectBox native library failed: vendor=%s,os=%s,os.arch=%s,sun.arch=%s,android=%s,linux=%s",
107-
vendor, osName, osArch, sunArch, android, isLinux
108+
"[ObjectBox] Loading native library failed, please report this to us: " +
109+
"vendor=%s,os=%s,os.arch=%s,model=%s,android=%s,linux=%s,machine=%s",
110+
vendor, osName, osArch, sunArch, android, isLinux, getCpuArchOSOrNull()
108111
);
109112
throw new LinkageError(message, e); // UnsatisfiedLinkError does not allow a cause; use its super class
110113
}
111114
}
112115

116+
/**
117+
* Get CPU architecture of the JVM (Note: this can not be used for Android, Android decides arch on its own
118+
* and looks for library in appropriately named folder).
119+
* <p>
120+
* Note that this may not be the architecture of the actual hardware
121+
* (e.g. when running a x86 JVM on an amd64 machine).
122+
*/
113123
private static String getCpuArch() {
114124
String osArch = System.getProperty("os.arch");
115125
String cpuArch = null;
@@ -119,34 +129,70 @@ private static String getCpuArch() {
119129
cpuArch = "x64";
120130
} else if (osArch.equalsIgnoreCase("x86")) {
121131
cpuArch = "x86";
132+
} else if ("aarch64".equals(osArch) || osArch.startsWith("armv8") || osArch.startsWith("arm64")) {
133+
// 64-bit ARM
134+
cpuArch = "arm64";
122135
} else if (osArch.startsWith("arm")) {
123-
switch (osArch) {
124-
case "armv7":
125-
case "armv7l":
126-
case "armeabi-v7a": // os.arch "armeabi-v7a" might be Android only, but let's try anyway...
127-
cpuArch = "armv7";
128-
break;
129-
case "arm64-v8a":
130-
cpuArch = "arm64";
131-
break;
132-
case "armv6":
133-
cpuArch = "armv6";
134-
break;
135-
default:
136-
cpuArch = "armv6"; // Lowest version we support
137-
System.err.println("Unknown os.arch \"" + osArch + "\" - ObjectBox is defaulting to " + cpuArch);
138-
break;
136+
// 32-bit ARM
137+
if (osArch.startsWith("armv7") || osArch.startsWith("armeabi-v7")) {
138+
cpuArch = "armv7";
139+
} else if (osArch.startsWith("armv6")) {
140+
cpuArch = "armv6";
141+
} else if ("arm".equals(osArch)) {
142+
// JVM may just report "arm" for any 32-bit ARM, so try to check with OS.
143+
String cpuArchOSOrNull = getCpuArchOSOrNull();
144+
if (cpuArchOSOrNull != null) {
145+
String cpuArchOS = cpuArchOSOrNull.toLowerCase();
146+
if (cpuArchOS.startsWith("armv7")) {
147+
cpuArch = "armv7";
148+
} else if (cpuArchOS.startsWith("armv6")){
149+
cpuArch = "armv6";
150+
} // else use fall back below.
151+
} // else use fall back below.
152+
}
153+
if (cpuArch == null) {
154+
// Fall back to lowest supported 32-bit ARM version.
155+
cpuArch = "armv6";
156+
System.err.printf("[ObjectBox] 32-bit ARM os.arch unknown (will use %s), " +
157+
"please report this to us: os.arch=%s, machine=%s%n",
158+
cpuArch, osArch, getCpuArchOSOrNull());
139159
}
140160
}
141161
}
162+
// If os.arch is not covered above try a x86 version based on JVM bit-ness.
142163
if (cpuArch == null) {
143164
String sunArch = System.getProperty("sun.arch.data.model");
144-
cpuArch = "32".equals(sunArch) ? "x86" : "x64";
145-
System.err.println("Unknown os.arch \"" + osArch + "\" - ObjectBox is defaulting to " + cpuArch);
165+
if ("64".equals(sunArch)) {
166+
cpuArch = "x64";
167+
} else if ("32".equals(sunArch)) {
168+
cpuArch = "x86";
169+
} else {
170+
cpuArch = "unknown";
171+
}
172+
System.err.printf("[ObjectBox] os.arch unknown (will use %s), " +
173+
"please report this to us: os.arch=%s, model=%s, machine=%s%n",
174+
cpuArch, osArch, sunArch, getCpuArchOSOrNull());
146175
}
147176
return cpuArch;
148177
}
149178

179+
/**
180+
* Get architecture using operating system tools. Currently only Linux is supported (using uname).
181+
*/
182+
@Nullable
183+
private static String getCpuArchOSOrNull() {
184+
String archOrNull = null;
185+
try {
186+
// Linux
187+
Process exec = Runtime.getRuntime().exec("uname -m");
188+
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
189+
archOrNull = reader.readLine();
190+
reader.close();
191+
} catch (Exception ignored) {
192+
}
193+
return archOrNull;
194+
}
195+
150196
private static void checkUnpackLib(String filename) {
151197
String path = "/native/" + filename;
152198
URL resource = NativeLibraryLoader.class.getResource(path);

0 commit comments

Comments
 (0)