title: UnsatisfiedLinkError in native method
body: <p>I m getting unsatisfied link error in native method </p>
  
  <p>Logcat main exception</p>
  
  <pre><code>UnsatisfiedLinkError: Native method not found: rg.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec:()Z
  </code></pre>
  
  <p>Complete Logcat</p>
  
  <pre><code>02-04 16:29:12.807: E/AndroidRuntime(5087): FATAL EXCEPTION: main
  02-04 16:29:12.807: E/AndroidRuntime(5087): java.lang.UnsatisfiedLinkError: Native method not found: org.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec:()Z
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteConnection.nativeHasCodec(Native Method)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteConnection.hasCodec(SQLiteConnection.java:160)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteDatabase.hasCodec(SQLiteDatabase.java:2195)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteConnectionPool.setMaxConnectionPoolSizeLocked(SQLiteConnectionPool.java:952)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteConnectionPool.&lt;init&gt;(SQLiteConnectionPool.java:153)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:179)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:804)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:789)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at org.sqlite.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at com.example.samplesqlitedb.SearchDataDB.getAutoSuggestion(SearchDataDB.java:33)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at com.example.samplesqlitedb.MainActivity$2.onClick(MainActivity.java:56)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.view.View.performClick(View.java:4084)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.view.View$PerformClick.run(View.java:16966)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.os.Handler.handleCallback(Handler.java:615)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.os.Handler.dispatchMessage(Handler.java:92)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.os.Looper.loop(Looper.java:137)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at android.app.ActivityThread.main(ActivityThread.java:4745)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at java.lang.reflect.Method.invokeNative(Native Method)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at java.lang.reflect.Method.invoke(Method.java:511)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
  02-04 16:29:12.807: E/AndroidRuntime(5087):     at dalvik.system.NativeStart.main(Native Method)
  </code></pre>
  
  <p>Custom Java file SQLiteConnection
       <a href="https://www.dropbox.com/s/5ex6u9rzkwb7kqq/SQLiteConnection.java" rel="noreferrer">https://www.dropbox.com/s/5ex6u9rzkwb7kqq/SQLiteConnection.java</a>
  error on line no. 160</p>
  
  <p>Here is the source cpp files from where i have compiled and created the binary "libsqliteX.so" file <a href="http://www.sqlite.org/android/tree?ci=trunk&amp;re=jni|src/org/sqlite/data&amp;expand" rel="noreferrer">http://www.sqlite.org/android/tree?ci=trunk&amp;re=jni|src/org/sqlite/data&amp;expand</a></p>
  
  <p>my .so file <a href="https://www.dropbox.com/s/d0u5pyhke54tcd6/libsqliteX.so" rel="noreferrer">https://www.dropbox.com/s/d0u5pyhke54tcd6/libsqliteX.so</a></p>
  
  <p>so i think i have to modify in the native method to resolve this problem</p>
  
  <pre><code>static jboolean nativeHasCodec(JNIEnv* env, jobject clazz){
  #ifdef SQLITE_HAS_CODEC
  return true;
  #else
  return false;
  #endif
  }
  </code></pre>
  
  <p>Here is CDT GLOBAL BUILD CONSOLE</p>
  
  <pre><code>**** Build of configuration Default for project CustomSqlite ****
  
  D:\software\adt-bundle-windows-x86-20130522\adt-bundle-windows-x86-20130522\android-ndk-r9-windows-x86\android-ndk-r9\ndk-build.cmd all 
  "Compile++ thumb : sqliteX &lt;= android_database_SQLiteCommon.cpp
  "Compile++ thumb : sqliteX &lt;= android_database_SQLiteConnection.cpp
  "Compile++ thumb : sqliteX &lt;= android_database_SQLiteGlobal.cpp
  "Compile++ thumb : sqliteX &lt;= android_database_SQLiteDebug.cpp
  "Compile++ thumb : sqliteX &lt;= JNIHelp.cpp
  "Compile++ thumb : sqliteX &lt;= JniConstants.cpp
  "Compile thumb : sqliteX &lt;= sqlite3.c
  SharedLibrary  : libsqliteX.so
  Install        : libsqliteX.so =&gt; libs/armeabi/libsqliteX.so
  
  **** Build Finished ****
  
  **** Build of configuration Default for project CustomSqlite ****
  
  D:\software\adt-bundle-windows-x86-20130522\adt-bundle-windows-x86-20130522\android-ndk-r9-windows-x86\android-ndk-r9\ndk-build.cmd all 
  Install        : libsqliteX.so =&gt; libs/armeabi/libsqliteX.so
  
  **** Build Finished ****
  </code></pre>
  
  <p>so i think .so was generated properly</p>
  
  <p>Here is my Customsqlite.java </p>
  
  <p>it is having methods </p>
  
  <pre><code>package org.sqlite.app.customsqlite;
  
  import java.io.File;
  import java.io.FileInputStream;
  import java.util.ArrayList;
  import java.util.Arrays;
  import org.sqlite.database.DatabaseErrorHandler;
  import org.sqlite.database.sqlite.SQLiteDatabase;
  import org.sqlite.database.sqlite.SQLiteOpenHelper;
  import org.sqlite.database.sqlite.SQLiteStatement;
  import android.app.Activity;
  import android.content.Context;
  import android.database.Cursor;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.View;
  import android.widget.EditText;
  import android.widget.TextView;
  
  class DoNotDeleteErrorHandler implements DatabaseErrorHandler {
  private static final String TAG = "DoNotDeleteErrorHandler";
  public void onCorruption(SQLiteDatabase dbObj) {
      Log.e(TAG,"Corruption reported by sqlite on database: " + dbObj.getPath());
  }
  }
  
  public class CustomSqlite extends Activity {
  private TextView myTV;  
  EditText query;
  File DB_PATH;
  String searchedword;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      myTV = (TextView) findViewById(R.id.tv_widget);
      query = (EditText) findViewById(R.id.query);
  }
  
  public void report_version() {
      SQLiteDatabase db = null;
      SQLiteStatement st;
      String res;
  
      db = SQLiteDatabase.openOrCreateDatabase(":memory:", null);
      st = db.compileStatement("SELECT sqlite_version()");
      res = st.simpleQueryForString();
  
      myTV.append("SQLite version " + res + "\n\n");
  }
  
  public void test_warning(String name, String warning) {
      myTV.append("WARNING:" + name + ": " + warning + "\n");
  }
  
  public void test_result(String name, String res, String expected) {
      myTV.append(name + "... ");
  
  
      if (res.equals(expected)) {
          myTV.append("ok\n");
      } else {
  
          myTV.append("FAILED\n");
          myTV.append("   res=     \"" + res + "\"\n");
          myTV.append("   expected=\"" + expected + "\"\n");
      }
  }
  
  /*
   * * Test if the database at DB_PATH is encrypted or not. The db* is assumed
   * to be encrypted if the first 6 bytes are anything* other than "SQLite".**
   * If the test reveals that the db is encrypted, return the string*
   * "encrypted". Otherwise, "unencrypted".
   */
  public String db_is_encrypted() throws Exception {
      FileInputStream in = new FileInputStream(DB_PATH);
      byte[] buffer = new byte[6];
      in.read(buffer, 0, 6);
      String res = "encrypted";
      if (Arrays.equals(buffer, (new String("SQLite")).getBytes())) {
          res = "unencrypted";
      }
      in.close();
      return res;
  }
  
  /*
   * * Use a Cursor to loop through the results of a SELECT query.
   */
  public void syno() throws Exception {
      DB_PATH = new File("/storage/sdcard1/sk2.db");
      SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
      Cursor c = db.rawQuery("SELECT synsetid, w2.lemma FROM sense LEFT JOIN word AS w2 ON w2.wordid=sense.wordid WHERE sense.synsetid IN (SELECT sense.synsetid FROM word AS w1 LEFT JOIN sense ON w1.wordid=sense.wordid WHERE w1.lemma='"+ searchedword+ "') AND w2.lemma&lt;&gt;'"+ searchedword + "'", null);
      ArrayList&lt;String&gt; list1 = new ArrayList&lt;String&gt;();
      if (c != null) {
  
          if (c.getCount() &gt; 0) {
              c.moveToFirst();
              do {
                  list1.add(c.getString(1));
              } while (c.moveToNext());
  
              }
          myTV.append("\n\nSYNONYM " + list1.toString());
      }
  
  
  
      db.close();
  
  }
  
  /*
   * * If this is a SEE build, check that encrypted databases work.
   */
  public void anto() throws Exception {
  
  SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
      Cursor c = db.rawQuery("SELECT DISTINCT(w2.lemma) as lemma from word w1 left join sense se1 on w1.wordid = se1.wordid left join synset sy1 on se1.synsetid = sy1.synsetid left join lexlinkref on sy1.synsetid = lexlinkref.synset1id and w1.wordid = lexlinkref.word1id left join word w2 on lexlinkref.word2id = w2.wordid where w1.lemma = '"+ searchedword + "' and lexlinkref.linkid=30",null);
      ArrayList&lt;String&gt; list1 = new ArrayList&lt;String&gt;();
      if (c.getCount() &gt; 0) {
          c.moveToFirst();
          do {            
          list1.add(c.getString(0));
          } while (c.moveToNext());
  
      }
      myTV.append("\n\nANTONYMS "+list1.toString());
      db.close();
  
  
  }
  
  class MyHelper extends SQLiteOpenHelper {
      public MyHelper(Context ctx) {
          super(ctx, DB_PATH.getPath(), null, 1);
      }
  
      public void onConfigure(SQLiteDatabase db) {
          db.execSQL("PRAGMA key = 'secret'");
      }
  
      public void onCreate(SQLiteDatabase db) {
          db.execSQL("CREATE TABLE t1(x)");
      }
  
      public void onUpgrade(SQLiteDatabase db, int iOld, int iNew) {
      }
  }
  
  /*
   * * If this is a SEE build, check that SQLiteOpenHelper still works.
   */
  public void def() throws Exception {
      DB_PATH = new File("/storage/sdcard1/sk2.db");
      String DEFINITION = "select pos, definition, sample FROM word INNER JOIN sense ON word.wordid = sense.wordid INNER JOIN synset ON sense.synsetid = synset.synsetid LEFT JOIN sample ON sample.synsetid =  synset.synsetid  WHERE lemma ='"+ searchedword + "'";
      SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(DB_PATH, null);
      ArrayList&lt;String&gt; list1 = new ArrayList&lt;String&gt;();
      Cursor mcursor = db.rawQuery(DEFINITION, null);
      mcursor.moveToFirst();
      if (mcursor.getCount() &gt; 0) {
          do {
  
              list1.add(mcursor.getString(1));
          } while (mcursor.moveToNext());
  
      }
      myTV.append("\nDEFINATION " + list1.toString());
      db.close();
  }
  
  public void run_the_tests(View view) {
      System.loadLibrary("sqliteX");
      myTV.setText("");       
      searchedword = query.getText().toString();
      try {
          report_version();
          def();
          syno();
          anto();
  
      } catch (Exception e) {
          myTV.append("Exception: " + e.toString() + "\n");
          myTV.append(android.util.Log.getStackTraceString(e) + "\n");
      }
  }
  }
  </code></pre>
  
  <p>Thanks</p>