xerial / sqlite-jdbc

SQLite JDBC Driver
Apache License 2.0
2.86k stars 619 forks source link

UnsatisfiedLinkError with SQLite JDBC Driver Using System libsqlite3.so on Linux and other OSs #1179

Closed blakemcbride closed 2 months ago

blakemcbride commented 2 months ago

Describe the bug

When using the SQLite JDBC driver with the system-installed libsqlite3.so on both Linux and OpenIndiana platforms (and presumably others), the Java application fails with an UnsatisfiedLinkError. The driver cannot find the required JNI method implementations in the system's SQLite library.

To Reproduce

  1. Install the SQLite JDBC driver (e.g., sqlite-jdbc-3.46.1.0.jar).

  2. Ensure that the system's libsqlite3.so is present in /usr/lib64.

  3. Run the Java application with the following JVM options:

java \
-Dorg.sqlite.lib.path=/usr/lib64 \
-Dorg.sqlite.lib.name=libsqlite3.so \
-cp .:sqlite-jdbc-3.46.1.0.jar YourMainClass
  1. Use the following sample code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class YourMainClass {
    public static void main(String[] args) {
        String url = "jdbc:sqlite:test.db";
        try (Connection conn = DriverManager.getConnection(url)) {
            if (conn != null) {
                System.out.println("Connection established.");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

Expected behavior

The application should successfully establish a connection to the SQLite database using the system-installed libsqlite3.so without any errors.

Logs

Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void org.sqlite.core.NativeDB._open_utf8(byte[], int)'
    at org.sqlite.core.NativeDB._open_utf8(Native Method)
    at org.sqlite.core.NativeDB.open(NativeDB.java:122)
    at org.sqlite.core.DB.open(DB.java:169)
    at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:247)
    at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:228)
    at org.sqlite.JDBC.createConnection(JDBC.java:124)
    at org.sqlite.JDBC.connect(JDBC.java:99)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
    at YourMainClass.main(YourMainClass.java:8)

Environment (please complete the following information):

Additional context

gotson commented 2 months ago

that can't work, because of this:

  • The system libsqlite3.so lacks the JNI bindings required by the SQLite JDBC driver.

This is how JNI works, you need a specifically compiled library containing the JNI code.

You can check how to compile against your own version of sqlite here: https://github.com/xerial/sqlite-jdbc/blob/02bac1a4a5d28a08334d197d3a3bb246fab9cb05/.github/workflows/ci.yml#L161-L181

blakemcbride commented 2 months ago

Then, what is the purpose of: -Dorg.sqlite.lib.path=/usr/lib64 -Dorg.sqlite.lib.name=libsqlite3.so

gotson commented 2 months ago

Then, what is the purpose of: -Dorg.sqlite.lib.path=/usr/lib64 -Dorg.sqlite.lib.name=libsqlite3.so

to use the binaries you have compiled yourself, for example for architectures that we don't ship in the jar, or if you build against your own amalgamation (as in the workflow i linked above). Or to use a specific version of SQLite that you could have extracted from a previous version of the sqlite-jdbc jar.