2

I am asking this question again because I have to.

I am having this error while running a NDK based application.

D dalvikvm: No JNI_OnLoad found in /data/app-lib/com.venky-1/libme.so 0xa5082228, skipping init W dalvikvm: No implementation found for native Lcom/venky/Home;.getPermission:(Landroid/app/Activity;)I

I have been through

  1. No JNI_OnLoad found in ... skipping init
  2. No JNI_OnLoad found skipping init > Application shutdown
  3. No JNI_Onload() found and VM shutting down
  4. JNI_OnLoad not found

Their problem was either

  1. They were not using JNI_OnLoad because they used JNI specific naming convention (For example Java_com_venky_Home_start()). Hence this message has no significance as there is an alternative.
  2. They were using C++ and there was function name mangling.

My case is entirely different. And the above two are invalid in my case. I am using C files. So no mangling. And I am not using JNI kind of function names. I am manually registering the functions using JNI_OnLoad. Hence my conclusion is that "No Implementation Found" is due to the fact that the application is somehow unable to find JNI_OnLoad. But why? It is present in the C file.

Relevant sections of code are as follows. Please ask if you need more.

jni/Android.mk

include $(CLEAR_VARS)
LOCAL_MODULE := me
LOCAL_SRC_FILE := me.c
include $(BUILD_SHARED_LIBRARY)

com/venky/Home.java

package com.venky;

import android.app.Activity;
import android.os.Bundle;

public class Home extends Activity {

    static {
        System.loadLibrary("me");
    }


    private native int getPermission(Activity activity);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);
        getPermission(this);
    }
}

jni/me.c

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <android/log.h>
#include <jni.h>

#define LOG_TAG "com.venky.me"

#define LOG_D(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOG_F(fn_name) __android_log_write(ANDROID_LOG_DEBUG, LOG_TAG, "Called : " fn_name )

static JavaVM *java_vm;

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
    LOG_F ("JNI_OnLoad");
    java_vm = vm;

    // Get JNI Env for all function calls
    JNIEnv* env;
    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_6) != JNI_OK) {
        LOG_D ("GetEnv failed.");
        return -1;
    }

    // Find the class calling native function
    jclass NativeUsb = (*env)->FindClass(env, "com/venky/Home");
    if (class_home == NULL) {
        LOG_D ("FindClass failed : No class found.");
        return -1;
    }

    // Register native method for getUsbPermission
    JNINativeMethod nm[1] = {
        { "getPermission", "(Landroid/app/Activity;)I", get_permission}
    };

    if ((*env)->RegisterNatives(env, NativeUsb, nm , 1)) {
         LOG_D ("RegisterNatives Failed.");
         return -1;
    }

    return JNI_VERSION_1_6;
}

int get_permission (jobject activity)
{
    LOG_F ("get_usb_permission");

}
Community
  • 1
  • 1
venky
  • 2,141
  • 3
  • 16
  • 20
  • 1
    What does `nm -D libmy.so` say? See http://stackoverflow.com/a/23044991/192373 – Alex Cohn Jun 15 '14 at 20:58
  • `00002010 A __bss_start U __cxa_atexit U __cxa_finalize 00002010 A _edata 00002010 A _end U __stack_chk_fail` – venky Jun 16 '14 at 04:34
  • @AlexCohn As can be seen, there is a problem with the library. Sorry for the above unformatted text though. I tried but could not make it in a code format. Any ideas why the shared object is incorrectly formed? – venky Jun 16 '14 at 04:36
  • 1
    Comments here ignore linebreaks, but you can link to pastebin.com, or update the question. I would like to see the output of clean `ndk-build V=1` – Alex Cohn Jun 16 '14 at 04:39
  • 1
    @AlexCohn I got the reason for the error. Please see the answer below. It was stupid. – venky Jun 16 '14 at 04:51

1 Answers1

2

By help of @AlexCohn, I found out my error. And what a silly stupid error it was.

jni/Android.mk

  include $(CLEAR_VARS)
  LOCAL_MODULE := me
- LOCAL_SRC_FILE := me.c
+ LOCAL_SRC_FILES := me.c
  include $(BUILD_SHARED_LIBRARY)

Because of this, me.c wasn't compiling. Hence it was not included in the built shared library. I had wasted a couple of hours on this at least.

venky
  • 2,141
  • 3
  • 16
  • 20