7

I'm trying to use xerial sqlite-jdbc to manage my database in Android with no success.I'm getting an java.lang.NoClassDefFoundError: org.sqlite.SQLiteConnection exception.I've imported this dependency 'org.xerial:sqlite-jdbc:3.18.0' in my gradle. My code is as follows,

 try {

        Class.forName("org.sqlite.JDBC");
        Connection connection = DriverManager.getConnection("jdbc:sqlite:hs.db");

    } catch (ClassNotFoundException eString) {System.err.println("Could not init JDBC driver - driver not found");
    } catch (java.sql.SQLException e) {e.printStackTrace();}

Using android.database.sqlite in my project is not option so please don't suggest that as an answer.

tasgr86
  • 299
  • 2
  • 7
  • 17
  • Official support for that library appears to be [in this Google Group](http://groups.google.com/group/xerial?hl=en), based on [the documentation](https://github.com/xerial/sqlite-jdbc#public-discussion-forum). – CommonsWare May 24 '17 at 13:36

4 Answers4

4

Gradle

 compile 'org.sqldroid:sqldroid:1.0.3'

JAVA

import java.sql.DriverManager;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.SQLException;

public class MainActivity extends AppCompatActivity {

    private Connection connection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            DriverManager.registerDriver((Driver) Class.forName("org.sqldroid.SQLDroidDriver").newInstance());
        } catch (Exception e) {
            throw new RuntimeException("Failed to register SQLDroidDriver");
        }
        String jdbcUrl = "jdbc:sqldroid:" + "/data/data/" + getPackageName() + "/my-database.db";
        try {
            this.connection = DriverManager.getConnection(jdbcUrl);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void onDestroy() {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        super.onDestroy();
    }
}

https://github.com/SQLDroid/SQLDroid

dherediat
  • 146
  • 13
  • As i said that's not an option for this project.I have to use a JDBC connection – tasgr86 May 25 '17 at 09:17
  • Thanks.That is what i was using until recently.But after a recent upgrade of gradle and Android Studio i get this exception "java.lang.NoClassDefFoundError: org.sqlite.SQLiteConnection".So i'm trying xerial now but i have the same problem. – tasgr86 May 25 '17 at 11:55
  • that could be the xerial jdbc isnt installed, try clean the project if dont work try less this line Class.forName("org.sqlite.JDBC"); because in the github repository haven´t this line https://github.com/xerial/sqlite-jdbc – dherediat May 25 '17 at 12:00
4

I needed to share some database code between my server DB and my phone DB, so I spent a lot of time writing the common code to use JDBC.

However, what I found out, after already being neck deep in this endeavor, is that there essentially isn't a working JDBC implementation on Android. I would strongly urge you not to go down this path - both Xerial and SQLDroid JDBC drivers have significant problems that I uncovered only during testing.

Problems with Xerial

It just doesn't work on Android :) It doesn't even load - I ran into this issue and couldn't work around it even after trying for hours.

Problems with SQLDroid

  1. See the Open Issues page - some of them were pretty scary to me. The deal breaker for me was the lack of batch support.
  2. See the Known Issues page before you start.

Finally, I ended up creating an implementation of the small subset of the java.sql interfaces and methods that I needed, using the android.database.sqlite classes. This was far less painful than I imagined (it took me just a couple of hours, for the subset of the functionality I needed) and it works great!

Vijayendra Vasu
  • 271
  • 3
  • 7
  • Can you say more about "an implementation of the small subset of java.sql interfaces and methods that I needed" ? Did you use that same subset on the server? What API did you use to implement it? Is there a more direct sqlite API in java? – dfrankow Dec 19 '21 at 16:07
  • For each java.sql interface that I was using on the server, I created a class in my Android project. For instance, for the `java.sql.Connection` interface, I created the following class: `public final class SQLiteConnection implements Connection` I then in Android Studio, I choose the 'Implement methods' action to create dummy implementations of each of its methods. I then implemented only those methods that I actually used using `android.database.sqlite` classes. I hope this clarifies. There are many SQLite JDBC implementations, but I couldn't find any (in 2019) that worked on Android. – Vijayendra Vasu Dec 21 '21 at 03:03
  • In the page https://github.com/xerial/sqlite-jdbc it was wrote "Download sqlite-jdbc-(VERSION).jar from the download page (or by using Maven) then append this jar file into your classpath." it was not correct to say "It just doesn't work on Android " – Kodomo May 02 '22 at 14:24
3

Here's my way:

  1. do some config in app/build.gradle, and copy a so file, looks ugly, but really works in my Android 9.0 system.
android {
    defaultConfig {
        ndk {
            abiFilters "armeabi-v7a"
        }
    }
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}
dependencies {
    implementation 'org.xerial:sqlite-jdbc:3.34.0'
}
  1. then copy this file sqlite-jdbc-3.34.0.jar!\org\sqlite\native\Linux\android-arm\libsqlitejdbc.so to app/libs/armeabi-v7a/, which looks like this: enter image description here.

  2. and the built apk looks like: enter image description here

  3. now you can enjoy javax.sql.DataSource of sqlite on android.

mysh
  • 383
  • 2
  • 10
  • In my case I had to define following lines in the proguard rules file: -keep class org.sqlite.** { *; } -keepnames class org.sqlite.** { *; } – Petterson Apr 29 '21 at 06:52
  • this should be most corect answer , since the instruction of xerial written: copy so in project path. – Kodomo May 02 '22 at 16:35
0

update gradle plugin version and gradle version to latest version

File -> Project Structure

project structure image

younes
  • 1
  • 3