2009-11-23 13 views
5

मैं जेएनआई के साथ अपने पैरों को गीला करने की कोशिश कर रहा हूं क्योंकि मेरे पास सी में एक एप्लीकेशन है जिसे एक जावा लाइब्रेरी फ़ंक्शन (कोई सी-समकक्ष लाइब्रेरी) तक पहुंचने की आवश्यकता नहीं है। मैंने सी से जावा वीएम लोड करने के लिए एक बहुत ही सरल परीक्षण कार्यक्रम लिखा है और एक स्थिर कार्य को कॉल करें और वापसी मूल्य प्राप्त करें।जेएनआई आमंत्रण API - NoClassDefFoundError (सी/जावा)

दुर्भाग्यवश, मैं कक्षा को उचित रूप से लोड करने में असमर्थ हूं। यद्यपि यह शायद इसे उबाल लेगा, मुझे लगता है कि मेरा क्लासपाथ सही है: जब मैं उसी निर्देशिका में उसी क्लासपाथ के साथ java कमांड का उपयोग करता हूं, तो कक्षा पूरी तरह लोड हो जाती है और निष्पादित होती है।

पर्यावरण:
Ubuntu 8.04 सर्वर
जावा JRE & एसडीके 1.6
जीसीसी

मेरे वर्तमान कार्यशील निर्देशिका हमेशा /home/me/project है।

[Loaded ...] 
[Loaded my.ClassABC from file:/home/me/project/] 
Exception in thread "main" java.lang.NoClassDefFoundError: my.ClassABC 
Failed to get class 

यहाँ है:

[Loaded ...] (many loads) 
[Loaded my.ClassABC from file:/home/me/project/] 
Hello test 
[Loaded java.lang.Shutdown from shared objects file] 
[Loaded java.lang.Shutdown$Lock from shared objects file] 

यहाँ जब मैं अपने सी कार्यक्रम (./myClassABC) चलाने मैं क्या मिलता है:

यहाँ जब मैं java आदेश (java -Djava.class.path=/home/me/project/ -verbose my.ClassABC) चलाने मैं क्या मिलता है मेरी जीसीसी कमांड लाइन:

gcc -o myClassABC myClassABC.c -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.16/include/linux -L/usr/lib/jvm/java-6-sun-1.6.0.16/jre/lib/i386/server/ -ljvm

मेरे सी कोड (myClassABC.c):

int main(int argc,char **argv) 
{ 
    JNIEnv *env; 
    JavaVM *jvm; 
    jint res; 
    jclass cls; 
    jmethodID mid; 
    jstring jstr; 
    jclass stringClass; 
    jobjectArray args; 

    JavaVMInitArgs vm_args; 
    JavaVMOption options[2]; 
    options[0].optionString = 
     "-Djava.class.path=."; // or "-Djava.class.path=/home/me/project/"; 
    options[1].optionString = 
     "-verbose"; 
    vm_args.version = JNI_VERSION_1_6; 
    vm_args.options = options; 
    vm_args.nOptions = 2; 
    vm_args.ignoreUnrecognized = JNI_FALSE; 
    /* Create the Java VM */ 
    res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); 

    if (res < 0) { 
     fprintf(stderr, "Can't create Java VM\n"); 
     exit(1); 
    } 
    if ((*env)->ExceptionOccurred(env)) { 
     (*env)->ExceptionDescribe(env); 
    } 

    cls = (*env)->FindClass(env,"my.ClassABC"); 
    if (cls == NULL) { 
     if ((*env)->ExceptionOccurred(env)) { 
      (*env)->ExceptionDescribe(env); 
     } 
     printf("Failed to get class\n"); 
     exit(1); 
    } 

    [call methods, etc.] 
} 

और मेरे जावा कोड, बस के लिए # $% @ s और गिगल्स (/home/me/project/my/ClassABC.class का संकलन किया जाता है):

package my; 

class ClassABC { 
    public static void main(String[] args) { 
     System.out.println(ClassABC.getPassword("test")); 
     return; 
    } 

    static String getPassword(String filename) 
    { 
     return "Hello "+filename; 
    } 
} 

धन्यवाद,
ब्रायन

उत्तर

10

बस इस

cls = (*env)->FindClass(env,"my.ClassABC"); 
को प्रतिस्थापित करें

cls = (*env)->FindClass(env,"my/ClassABC"); 

साथ

और आप ठीक होना चाहिए।

वरना जोड़ने

... 
JavaVMOption options[3]; 
... 
options[2].optionString = "-verbose:jni"; 
... 
+0

ओह यार, तुम बहुत बहुत धन्यवाद की कोशिश करो! विनिर्देश और चीजों पर वापस देखकर अब मैं देखता हूं कि मैंने उस पर ध्यान दिया। – HalfBrian