Skip to content

Commit 8e2e0ea

Browse files
ARM support: update JVM os.arch detection, use uname on Linux to decide v6 or v7.
1 parent 06eb86a commit 8e2e0ea

File tree

1 file changed

+45
-18
lines changed

1 file changed

+45
-18
lines changed

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

Lines changed: 45 additions & 18 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
*/
@@ -110,7 +112,16 @@ public class NativeLibraryLoader {
110112
}
111113
}
112114

115+
/**
116+
* Get CPU architecture of the JVM (Note: this can not be used for Android, Android decides arch on its own
117+
* and looks for library in appropriately named folder).
118+
* <p>
119+
* Note that this may not be the architecture of the actual hardware
120+
* (e.g. when running a x86 JVM on an amd64 machine).
121+
*/
113122
private static String getCpuArch() {
123+
// See https://github.com/openjdk/jdk/blob/master/make/autoconf/platform.m4 for possible values.
124+
// Note: any CPU architecture starting with "arm" is reported as "arm", aarch64 is reported as "aarch64".
114125
String osArch = System.getProperty("os.arch");
115126
String cpuArch = null;
116127
if (osArch != null) {
@@ -119,23 +130,22 @@ private static String getCpuArch() {
119130
cpuArch = "x64";
120131
} else if (osArch.equalsIgnoreCase("x86")) {
121132
cpuArch = "x86";
122-
} 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+
} else if (osArch.equals("aarch64")) {
134+
cpuArch = "arm64";
135+
} else if (osArch.equals("arm")) {
136+
// Decide if ARMv6 or ARMv7 library should be used, need to get actual architecture from OS.
137+
String cpuArchOSOrNull = getCpuArchOSOrNull();
138+
if (cpuArchOSOrNull != null) {
139+
String cpuArchOSlower = cpuArchOSOrNull.toLowerCase();
140+
if (cpuArchOSlower.startsWith("armv6")) {
133141
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;
142+
} else {
143+
// ARMv7 or 32-bit ARMv8
144+
cpuArch = "armv7";
145+
}
146+
} else {
147+
cpuArch = "armv7";
148+
System.err.println("Failed to get arch from OS - ObjectBox is defaulting to " + cpuArch);
139149
}
140150
}
141151
}
@@ -147,6 +157,23 @@ private static String getCpuArch() {
147157
return cpuArch;
148158
}
149159

160+
/**
161+
* Get architecture using operating system tools. Currently only Linux is supported (using uname).
162+
*/
163+
@Nullable
164+
private static String getCpuArchOSOrNull() {
165+
String archOrNull = null;
166+
try {
167+
// Linux
168+
Process exec = Runtime.getRuntime().exec("uname -m");
169+
BufferedReader reader = new BufferedReader(new InputStreamReader(exec.getInputStream()));
170+
archOrNull = reader.readLine();
171+
reader.close();
172+
} catch (Exception ignored) {
173+
}
174+
return archOrNull;
175+
}
176+
150177
private static void checkUnpackLib(String filename) {
151178
String path = "/native/" + filename;
152179
URL resource = NativeLibraryLoader.class.getResource(path);

0 commit comments

Comments
 (0)