Repository: xerial/sqlite-jdbc (java)

Issue:
Failed to load native library when running in Termux
This works fine on Windows, according to the README.md, it should also work adaptively on `Termux`, but it doesn't, am I doing something wrong?

**Codes**
```Kotlin
class MySQLiteTool(private val library: Path) {
    val connection: Connection by lazy {
        Class.forName("org.sqlite.JDBC")
        DriverManager.getConnection("jdbc:sqlite:$library")
    }
...
```
```KotlinScript
dependencies {
    implementation("org.xerial:sqlite-jdbc:3.39.3.0")
}
```

**Logs**
```
Failed to load native library:jansi-2.4.0-2db311a958a8e929-libjansi.so. osinfo: Linux/arm64
java.lang.UnsatisfiedLinkError: /data/data/com.termux/files/usr/tmp/jansi-2.4.0-2db311a958a8e929-libjansi.so: dlopen failed: library "libc.so.6" not found: needed by /data/data/com.termux/files/usr/tmp/jansi-2.4.0-2db311a958a8e929-libjansi.so in namespace (default)
...
...
2022-09-21 10:17:22 W/stderr: Failed to load native library:sqlite-3.36.0.3-ffd4f25b-64e0-4683-a009-8a70f7c36428-libsqlitejdbc.so. osinfo: Linux/aarch64
2022-09-21 10:17:22 W/stderr: java.lang.UnsatisfiedLinkError: /data/data/com.termux/files/usr/tmp/sqlite-3.36.0.3-ffd4f25b-64e0-4683-a009-8a70f7c36428-libsqlitejdbc.so: dlopen failed: library "libc.so.6" not found: needed by /data/data/com.termux/files/usr/tmp/sqlite-3.36.0.3-ffd4f25b-64e0-4683-a009-8a70f7c36428-libsqlitejdbc.so in namespace (default)
2022-09-21 10:17:22 E/AzurLaneLibrary: java.sql.SQLException: Error opening connection
java.sql.SQLException: Error opening connection
```

```
## Termux App Info
**APP_NAME**: `Termux`  
**PACKAGE_NAME**: `com.termux`  
**VERSION_NAME**: `0.118.0`  
**VERSION_CODE**: `118`  
**TARGET_SDK**: `28`  
## Device Info
### Hardware
**SUPPORTED_ABIS**: `arm64-v8a, armeabi-v7a, armeabi`  
```


Pull request:
Allow correct recognition of Android OS when running Termux environment
If `isAndroid()` check fails, `checkIfAndroidTermux()` is called which runs `uname -o` command and check if its output contains `android`. This should fix #789. 

Sample command output in Termux before changes:
![Screenshot_20221016-120121.png](https://user-images.githubusercontent.com/61787916/196029389-806d6c93-ba8e-49d9-8e2f-25fdb6108bed.png)

Sample command output in Termux after changes:
![Screenshot_20221016-120404.png](https://user-images.githubusercontent.com/61787916/196029453-2a88aad0-926b-4a79-837a-9428458e9e59.png)

Patch:
diff --git a/src/main/java/org/sqlite/util/OSInfo.java b/src/main/java/org/sqlite/util/OSInfo.java
index 81d4faab..a1f64395 100644
--- a/src/main/java/org/sqlite/util/OSInfo.java
+++ b/src/main/java/org/sqlite/util/OSInfo.java
@@ -111,9 +111,21 @@ public class OSInfo {
     }
 
     public static boolean isAndroid() {
+        return isAndroidRuntime() || isAndroidTermux();
+    }
+
+    public static boolean isAndroidRuntime() {
         return System.getProperty("java.runtime.name", "").toLowerCase().contains("android");
     }
 
+    public static boolean isAndroidTermux() {
+        try {
+            return processRunner.runAndWaitFor("uname -o").toLowerCase().contains("android");
+        } catch (Exception ignored) {
+            return false;
+        }
+    }
+
     public static boolean isMusl() {
         Path mapFilesDir = Paths.get("/proc/self/map_files");
         try (Stream<Path> dirStream = Files.list(mapFilesDir)) {


Test patch:
diff --git a/src/test/java/org/sqlite/util/OSInfoTest.java b/src/test/java/org/sqlite/util/OSInfoTest.java
index a07b043a..a6e05161 100644
--- a/src/test/java/org/sqlite/util/OSInfoTest.java
+++ b/src/test/java/org/sqlite/util/OSInfoTest.java
@@ -110,15 +110,35 @@ public class OSInfoTest {
     // it's unlikely we run tests on an Android device
     @Test
     void testIsNotAndroid() {
+        assertThat(OSInfo.isAndroidRuntime()).isFalse();
+        assertThat(OSInfo.isAndroidTermux()).isFalse();
         assertThat(OSInfo.isAndroid()).isFalse();
     }
 
+    @Test
+    public void testIsAndroidTermux() throws Exception {
+        try {
+            ProcessRunner mockRunner = mock(ProcessRunner.class);
+            OSInfo.processRunner = mockRunner;
+            when(mockRunner.runAndWaitFor("uname -o")).thenReturn("Android");
+
+            assertThat(OSInfo.isAndroidTermux()).isTrue();
+            assertThat(OSInfo.isAndroidRuntime()).isFalse();
+            assertThat(OSInfo.isAndroid()).isTrue();
+        } finally {
+            OSInfo.processRunner = new ProcessRunner();
+        }
+    }
+
     @Nested
     @SetSystemProperty(key = "java.runtime.name", value = "Java for Android")
     @SetSystemProperty(key = "os.name", value = "Linux for Android")
-    class Android {
+    class AndroidRuntime {
+
         @Test
-        public void testIsAndroid() {
+        public void testIsAndroidRuntime() {
+            assertThat(OSInfo.isAndroidRuntime()).isTrue();
+            assertThat(OSInfo.isAndroidTermux()).isFalse();
             assertThat(OSInfo.isAndroid()).isTrue();
         }