I am not sure that I have fully understood your setup and if you require this to be done from eclipse or not. Anyhow I was interested in doing a little test program using JNI and a Cocoa library doing nothing just to try the debugging of the obj-c/c code.
I succeeded to do this setup and also to debug the code. I use IntelliJ for Java and Xcode for the objc/c part but doing the java part in eclipse is a no-brainer.
So you should be able to set up exactly my project structure and get going with the debugging. And from there you should be able to apply this knowledge to your own more complex code.
This is how I started off:
- Create a new project in Xcode by choosing Cocoa Library.

- Name the project
libnative
and make it of Type Dynamic.

Choose a place for your new project. I use ~/Development/
and skip the Create local git...
part.
This will create a new project called lib native.xcodeproj
in your selected folder. Two files have been automatically created: libnative.h
and libnative.m
.
First you must change the Project Settings.
Executable Extension
in the Packaging
section must be changed from dynlib
to jnilib
.
Framework Search Paths
in the Search Paths
section must be updated to point to the JNI framework: /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/

- Now its time to add some code. Be aware that with this setup you will have to use
<JavaVM/jni.h>
. Update the libnative.m
to look like the following code:
//
// libnative.m
// libnative
//
// Created by maba on 2012-10-09.
// Copyright (c) 2012 maba. All rights reserved.
//
#import "libnative.h"
#include <JavaVM/jni.h>
@implementation libnative
@end
#ifdef __cplusplus
extern "C" {
#endif
#ifndef VEC_LEN
#define VEC_LEN(v) (sizeof(v)/sizeof(v[0]))
#endif/*VEC_LEN*/
static JavaVM *javaVM;
static void print();
static JNINativeMethod Main_methods[] =
{
{ "print", "()V", (void*)print },
};
static struct {
const char *class_name;
JNINativeMethod *methods;
int num_methods;
} native_methods[] = {
{ "com/stackoverflow/Main", Main_methods, VEC_LEN(Main_methods) },
};
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {
JNIEnv *env = 0;
jclass cls = 0;
jint rs = 0;
if ((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_4)) {
return JNI_ERR;
}
javaVM = jvm;
for (unsigned int i = 0; i < VEC_LEN(native_methods); i++) {
cls = (*env)->FindClass(env, native_methods[i].class_name);
if (cls == NULL) {
return JNI_ERR;
}
rs = (*env)->RegisterNatives(env, cls, native_methods[i].methods, native_methods[i].num_methods);
assert(rs == JNI_OK);
}
return JNI_VERSION_1_4;
}
static void print(JNIEnv *env, jclass cls) {
printf("Hello from C");
}
#ifdef __cplusplus
}
#endif
com.stackoverflow.Main.java
package com.stackoverflow;
/**
* @author maba, 2012-10-09
*/
public class Main {
static native void print();
static {
System.out.println(System.getProperty("java.library.path"));
System.loadLibrary("native");
}
public static void main(String[] args) {
System.out.println("Loading native");
Main.print();
}
}
- Set a breakpoint on the line before
Main.print();
. Start the debugger with the following JVM option:
-Djava.library.path="/Users/maba/Library/Developer/Xcode/DerivedData/libnative-cquleqohzyhghnercyqdwpnznjdf/Build/Products/Debug/"
This line is a little long and also user specific. You will have to look for yourself what the directory names are but they will be more or less the same as mine except for the generated libnative-cquleqohzyhghnercyqdwpnznjdf
path.
The program should be running and waiting at the breakpoint. Time to attach the Xcode debugger to the running application.
Choose menu Product
-> Attach to Process >
and point to the running java
process in the System
part of the drop down. If there are several java
processes then it is most likely the one with the highest PID but not always. You'll have to try.
Create a breakpoint in the c code on the line printf("Hello from C");
.
Go back to the Java IDE and continue the execution from where it was halting.
Go back to Xcode and see that it is waiting at the breakpoint!

As I stated earlier this is a very simple approach to the obj-c/JNI and your project is probably quite large but with this small test project you can at least see how it works and then continue to your own project setup.