EzDevInfo.com

jni interview questions

Top jni frequently asked interview questions

Calling a java method from c++ in Android

THE SOLUTION TO THIS PROBLEM IS IN THE BOTTOM OF THE QUESTION!


Hi. I'm trying to get a simple java method call from c++ while java calls native method. So, here's the java code:

public class MainActivity extends Activity {
    private static String LIB_NAME = "name";

    static {
        System.loadLibrary(LIB_NAME);
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView tv = (TextView) findViewById(R.id.textview);
        tv.setText(this.getJniString());
    }

    public void messageMe(String text) {
        System.out.println(text);
    }

    public native String getJniString();
}

I'm trying to call a messageMe method from native code in the process of getJniString method call from java to native.

native.cpp:

#include <string.h>
#include <stdio.h>
#include <jni.h>

jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj, jint depth ){

//    JavaVM *vm;
//    JNIEnv *env;
//    JavaVMInitArgs vm_args;
//    vm_args.version = JNI_VERSION_1_2;
//    vm_args.nOptions = 0;
//    vm_args.ignoreUnrecognized = 1;
//
//    // Construct a VM
//    jint res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);

    // Construct a String
    jstring jstr = env->NewStringUTF("This string comes from JNI");
    // First get the class that contains the method you need to call
    jclass clazz = env->FindClass("the/package/MainActivity");
    // Get the method that you want to call
    jmethodID messageMe = env->GetMethodID(clazz, "messageMe", "(Ljava/lang/String;)V");
    // Call the method on the object
    jobject result = env->CallObjectMethod(jstr, messageMe);
    // Get a C-style string
    const char* str = env->GetStringUTFChars((jstring) result, NULL);
    printf("%s\n", str);
        // Clean up
    env->ReleaseStringUTFChars(jstr, str);

//    // Shutdown the VM.
//    vm->DestroyJavaVM();

    return env->NewStringUTF("Hello from JNI!");
}

After clean compilation app stops with next message:

ERROR/AndroidRuntime(742): FATAL EXCEPTION: main
        java.lang.NoSuchMethodError: messageMe
        at *.android.t3d.MainActivity.getJniString(Native Method)
        at *.android.t3d.MainActivity.onCreate(MainActivity.java:22)

Apparently it means that method name is wrong, but it looks ok to me. Any ideas are welcome.

P.S.: I'm not a c/c++ guy, yet)


SOLUTION

So, I quite messed it up with c to c++ conversion (basically env variable stuff), but I got it working with next code for c:

#include <string.h>
#include <stdio.h>
#include <jni.h>

jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj){

    jstring jstr = (*env)->NewStringUTF(env, "This comes from jni.");
    jclass clazz = (*env)->FindClass(env, "com/inceptix/android/t3d/MainActivity");
    jmethodID messageMe = (*env)->GetMethodID(env, clazz, "messageMe", "(Ljava/lang/String;)Ljava/lang/String;");
    jobject result = (*env)->CallObjectMethod(env, obj, messageMe, jstr);

    const char* str = (*env)->GetStringUTFChars(env,(jstring) result, NULL); // should be released but what a heck, it's a tutorial :)
    printf("%s\n", str);

    return (*env)->NewStringUTF(env, str);
}

And next code for java methods:

    public class MainActivity extends Activity {
    private static String LIB_NAME = "thelib";

    static {
        System.loadLibrary(LIB_NAME);
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        TextView tv = (TextView) findViewById(R.id.textview);
        tv.setText(this.getJniString());
    }

    // please, let me live even though I used this dark programming technique
    public String messageMe(String text) {
        System.out.println(text);
        return text;
    }

    public native String getJniString();
}

Source: (StackOverflow)

java.lang.UnsatisfiedLinkError no *****.dll in java.library.path

How can I load a custom dll file in my web application? I tried following ways but its failing.

  • copied all required dlls in system32 folder and tried to load one of them in Servlet constructor System.loadLibrary
  • Copied required dlls in tomcat_home/shared/lib and tomcat_home/common/lib
  • all these dlls are in WEB-INF/lib of the web-application

Source: (StackOverflow)

Advertisements

How can I tell if I'm running in 64-bit JVM or 32-bit JVM (from within a program)?

How can I tell if the JVM my application runs in is 32 bit or 64-bit? Specifically, what function or preference do I access to detect this within the program?


Source: (StackOverflow)

What makes JNI calls slow?

I know that 'crossing boundaries' when making a JNI call in Java is slow.

However I want to know what is it that makes it slow? What does the underlying jvm implementation do when making a JNI call that makes it so slow?


Source: (StackOverflow)

Any simple or easy way to debug Android NDK code?

I'm looking for a way to easily debug C code in an Android NDK application using Eclipse. I've read ways to debug the app using gdb or something similar but what I want is a way to push messages to Eclipse somehow.

I'm looking for a solution that's as simple as using a print function in C and seeing it in the DDMS Log or anything similar. Does anyone have any experience doing this?


Source: (StackOverflow)

Java thread leaks when calling back from native thread via JNI

Summary: I am seeing Java thread leaks when calling back into Java from native code on a natively-created thread.

(Update 11 Feb 2014: We raised this as a support request with Oracle. It has now been confirmed by Oracle on Java 7 update 45. It only affects 64-bit Linux (and possibly Mac) platforms: 32-bit Linux is unaffected).

(Update 29 April 2014: Oracle have a fix for this issue, and it will be released in Java 7 update 80).

I have an application consisting of a Java layer and a native library. The Java layer calls into the native library via JNI: this then causes a new native thread to start running, which calls back into Java. Because the new native thread is not attached to the JVM, it needs to be attached prior to doing the callback, then detached afterwards. The usual way to do this seems to be to bracket the code that calls back into Java with AttachCurrentThread / DetachCurrentThread calls. This works fine, but for our application (which calls back into Java very frequently) the overhead of attaching and detaching every time is significant.

There is an optimization described in several places (like here and here) that recommends using mechanisms based on thread local storage to eliminate this problem: essentially every time the native callback is triggered, the thread is tested to see if it is already attached to the JVM: if not, it is attached to the JVM and the thread local storage mechanism is used to automatically detach the thread when it exits. I have implemented this, but although the attach and detach appears to be occurring correctly, this causes a leak of threads on the Java side. I believe I am doing everything correctly and am struggling to see what might be wrong. I have been bashing my head on this for a while now and I would be very grateful for any insights.

I have recreated the problem in cut-down form. Below is the code for the native layer. What we have here is a wrapper that encapsulates the process of returning a JNIEnv pointer for the current thread, using the POSIX thread-local storage mechanism to automatically detach the thread if it wasn't already attached. There is a callback class that acts as a proxy for the Java callback method. (I have used callback to a static Java method in order to eliminate the extra complication of creating and deleting global object references to the Java object, which are irrelevant to this problem). Finally there is a JNI method that when called, constructs a callback, and creates a new native thread and waits for it to complete. This newly created thread calls the callback once then exits.

#include <jni.h>
#include <iostream>
#include <pthread.h>


using namespace std;


/// Class to automatically handle getting thread-specific JNIEnv instance,
/// and detaching it when no longer required
class JEnvWrapper
{

public:

    static JEnvWrapper &getInstance()
    {
        static JEnvWrapper wrapper;
        return wrapper;
    }

    JNIEnv* getEnv(JavaVM *jvm)
    {
        JNIEnv *env = 0;
        jint result = jvm->GetEnv((void **) &env, JNI_VERSION_1_6);
        if (result != JNI_OK)
        {
            result = jvm->AttachCurrentThread((void **) &env, NULL);
            if (result != JNI_OK)
            {
                cout << "Failed to attach current thread " << pthread_self() << endl;
            }
            else
            {
                cout << "Successfully attached native thread " << pthread_self() << endl;
            }

            // ...and register for detach when thread exits
            int result = pthread_setspecific(key, (void *) env);
            if (result != 0)
            {
                cout << "Problem registering for detach" << endl;
            }
            else
            {
                cout << "Successfully registered for detach" << endl;
            }
        }

        return env;
    }

private:

    JEnvWrapper()
    {
        // Initialize the key
        pthread_once(&key_once, make_key);
    }

    static void make_key()
    {
        pthread_key_create(&key, detachThread);
    }


    static void detachThread(void *p)
    {
        if (p != 0)
        {
            JavaVM *jvm = 0;
            JNIEnv *env = (JNIEnv *) p;
            env->GetJavaVM(&jvm);
            jint result = jvm->DetachCurrentThread();
            if (result != JNI_OK)
            {
                cout << "Failed to detach current thread " << pthread_self() << endl;
            }
            else
            {
                cout << "Successfully detached native thread " << pthread_self() << endl;
            }

        }
    }


    static pthread_key_t key;
    static pthread_once_t key_once;
};

pthread_key_t JEnvWrapper::key;
pthread_once_t JEnvWrapper::key_once = PTHREAD_ONCE_INIT;



class Callback
{

public:

    Callback(JNIEnv *env, jobject callback_object)
    {
        cout << "Constructing callback" << endl;
        const char *method_name = "javaCallback";
        const char *method_sig = "(J)V";

        env->GetJavaVM(&m_jvm);

        m_callback_class = env->GetObjectClass(callback_object);
        m_methodID = env->GetStaticMethodID(m_callback_class, method_name, method_sig);
        if (m_methodID == 0)
        {
            cout << "Couldn't get method id" << endl;
        }
    }

    ~Callback()
    {
        cout << "Deleting callback" << endl;
    }

    void callback()
    {
        JNIEnv *env = JEnvWrapper::getInstance().getEnv(m_jvm);
        env->CallStaticVoidMethod(m_callback_class, m_methodID, (jlong) pthread_self());
    }

private:

    jclass m_callback_class;
    jmethodID m_methodID;
    JavaVM *m_jvm;
};



void *do_callback(void *p)
{
    Callback *callback = (Callback *) p;
    callback->callback();
    pthread_exit(NULL);
}




extern "C"
{

JNIEXPORT void JNICALL Java_com_test_callback_CallbackTest_CallbackMultiThread(JNIEnv *env, jobject obj)
{
    Callback callback(env, obj);
    pthread_t thread;
    pthread_attr_t attr;
    void *status;
    int rc;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    rc = pthread_create(&thread, &attr, do_callback, (void *) &callback);
    pthread_attr_destroy(&attr);
    if (rc)
    {
        cout << "Error creating thread: " << rc << endl;
    }
    else
    {
        rc = pthread_join(thread, &status);
        if (rc)
        {
            cout << "Error returning from join " << rc << endl;
        }
    }
}

The Java code is very simple: it just repeatedly calls the native method in a loop:

package com.test.callback;

public class CallbackTest
{

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

    public void runTest_MultiThreaded(int trials)
    {
        for (int trial = 0; trial < trials; trial++)
        {
            // Call back from this thread
            CallbackMultiThread();

            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    static void javaCallback(long nativeThread)
    {
        System.out.println("Java callback: native thread: " + nativeThread + ", java thread: " + Thread.currentThread().getName() + ", " + Thread.activeCount() + " active threads");
    }

    native void CallbackMultiThread();  
}

Below is some sample output from this test: you can see that although the native layer is reporting that the native thread is successfully being attached and detached, every time the callback is triggered a new Java thread is created:

Constructing callback
Successfully attached native thread 140503373506304
Successfully registered for detach
Java callback: native thread: 140503373506304, java thread: Thread-67, 69 active threads
Successfully detached native thread 140503373506304
Deleting callback
Constructing callback
Successfully attached native thread 140503373506304
Successfully registered for detach
Java callback: native thread: 140503373506304, java thread: Thread-68, 70 active threads
Successfully detached native thread 140503373506304
Deleting callback
Constructing callback
Successfully attached native thread 140503373506304
Successfully registered for detach
Java callback: native thread: 140503373506304, java thread: Thread-69, 71 active threads
Successfully detached native thread 140503373506304
Deleting callback
Constructing callback
Successfully attached native thread 140503373506304
Successfully registered for detach
Java callback: native thread: 140503373506304, java thread: Thread-70, 72 active threads
Successfully detached native thread 140503373506304
Deleting callback
Constructing callback
Successfully attached native thread 140503373506304
Successfully registered for detach
Java callback: native thread: 140503373506304, java thread: Thread-71, 73 active threads
Successfully detached native thread 140503373506304
Deleting callback

Just to add: the development platform I am using is CentOS 6.3 (64-bit). The Java version is the Oracle distribution version 1.7.0_45, although the problem also shows with the OpenJDK distribution, versions 1.7 and 1.6.


Source: (StackOverflow)

How to use the same C++ code for Android and iOS? [closed]

Android with NDK have support to C/C++ code and iOS with Objective-C++ have support too, so I want see a example of a program with native C/C++ code shared between Android and iOS.

Observation: I'll go answer this question following the Q&A-style.


Source: (StackOverflow)

Access C++ shared library from Java: JNI, JNA, CNI, or SWIG? [closed]

Which of the following (or other) method would you recommend for accessing a C++ shared library from Java and why?

  1. JNI: I hear this has a number of pitfalls and is quite the undertaking?
  2. SWIG: Apparently this makes using JNI easier, but I've heard it has some problems too?
  3. JNA: I could write a C interface and then use JNA with it instead, which is apparently significantly easier than JNI?
  4. CNI: Apparently this is easier than JNI?
  5. Another library: it can't be commercial and I'd prefer something that is still well maintained (this would throw out JNIEasy, JNative, and JACE - I think).

I'm trying to go for minimal development time and problems down the road. Any info on pros/cons of each of these would be appreciated.

EDIT: Optimally, I'd be able to use my C++ objects in Java, but as I mentioned in #3, I could write a C interface using just functions if absolutely necessary. The C++ interface I'd like to have available in Java is something like:

class MyObj1
{
    MyObj1(std::string, bool);
    bool Func1();
    void Func2(bool);
}

class MyObj2
{
    MyObj2(MyObj1*);
    ssize_t Func(uint8_t *, size_t, MyObj1);
}

The actual interface is a bit more complicated, but this demonstrates the type of objects and methods I'll be using. Some of the objects are derived, but the Java interface does not need to have any polymorphic behavior.


Source: (StackOverflow)

How to bundle a native library and a JNI library inside a JAR?

The library in question is Tokyo Cabinet.

I want is to have the native library, JNI library, and all Java API classes in one JAR file to avoid redistribution headaches.

There seems to be an attempt at this at GitHub, but

  1. It does not include the actual native library, only JNI library.
  2. It seems to be specific to Leiningen's native dependencies plugin (it won't work as a redistributable).

The question is, can I bundle everything in one JAR and redistribute it? If yes, how?

P.S.: Yes, I realize it may have portability implications.


Source: (StackOverflow)

How can I catch SIGSEGV (segmentation fault) and get a stack trace under JNI on Android?

I'm moving a project to the new Android Native Development Kit (i.e. JNI) and I'd like to catch SIGSEGV, should it occur (possibly also SIGILL, SIGABRT, SIGFPE) in order to present a nice crash reporting dialog, instead of (or before) what currently happens: the immediate unceremonious death of the process and possibly some attempt by the OS to restart it. (Edit: The JVM/Dalvik VM catches the signal and logs a stack trace and other useful information; I just want to offer the user the option to email that info to me really.)

The situation is: a large body of C code which I didn't write does most of the work in this application (all the game logic) and although it's well-tested on numerous other platforms, it's entirely possible that I, in my Android port, will feed it garbage and cause a crash in native code, so I want the crash dumps (both native and Java) that currently show up in the Android log (I guess it would be stderr in a non-Android situation). I'm free to modify both C and Java code arbitrarily, although the callbacks (both going in and coming out of JNI) number about 40 and obviously, bonus points for small diffs.

I've heard of the signal chaining library in J2SE, libjsig.so, and if I could safely install a signal handler like that on Android, that would solve the catching part of my question, but I see no such library for Android/Dalvik.


Source: (StackOverflow)

Eclipse reported "Failed to load JNI shared library" [duplicate]

Possible Duplicate:
Failed to Load the JNI shared Library (JDK)

I can't open Eclipse because I get an alert that says

Failed to load JNI shared library C:\Program Files (x86)\eclipse\jre\bin\client\jvm.dll

I've found a kind of solution on YouTube, Eclipse Failed to load JNI library fix.

He says that you only have to download a JRE 7 folder. Then I just have to replace C:\Program Files (x86)\Java\jre7\bin\server\jvm.dll with C:\Program Files (x86)\eclipse\jre\bin\client\jvm.dll.

But where is the JRE 7 link?


Source: (StackOverflow)

Failed to load the JNI shared Library (JDK)

When I try opening Eclipse, a pop-up dialog states:

Failed to load the JNI shared library "C:/JDK/bin/client/jvm.dll"`.

Following this, Eclipse force closes.

Here's a few points I'd like to make:

  • I checked to see if anything exists at that path. It does exist.
  • My Eclipse and Java SE Development Kit are both 64-bit. I checked my system, and it can handle 64-bit.
  • I've searched for this problem on Google and on Stack Overflow, and the only answer I found was to download the 32-bit versions of JDK and Eclipse.

Downloading the 32-bit versions is something I only want to do as a very last resort.
What would be suggested to solve this issue?


Source: (StackOverflow)

How to return an array from JNI to Java?

I am attempting to use the android NDK.

Is there a way to return an array (in my case an int[]) created in JNI to Java? If so, please provide a quick example of the JNI function that would do this.

-Thanks


Source: (StackOverflow)

JNI converting jstring to char *

I have passed a URL string from Java to C code as jstring data type through the use of JNI. And my library method needs a char * as url.

How can I convert jstring in char * ?

P.S.: Is there any advantage of using jcharArray in C? (i.e. Passing char [] instead of string in native method)


Source: (StackOverflow)

Javah error while using it in JNI

Command:

javah -jni JavaHowTo

Result:

error: cannot access JavaHowTo 
class file for JavaHowTo not found

javadoc: error - Class JavaHowTo not found.
Error: No classes were specified on the command line.  Try -help.

I have set the class path correctly, but still i am getting this javah error.

Any solution for this will be much helpful.


Source: (StackOverflow)