Hunter McMillen
Hunter McMillen

Reputation: 61515

Undefined Reference Trying to invoke Java from C++

I am trying to create a Java virtual machine from C++ and invoke the main method passing a String argument to the main method of the Java program. I am following this example found on Sun's website: http://java.sun.com/docs/books/jni/html/invoke.html#11202

Here is the simple Java Program:

public class TestJNIInvoke
{
    public static void main(String[] args)
    {
    System.out.println(args[0]);
    }
}

Here is the C++ program I am using to (try to) invoke the JVM:

#include <jni.h>
#include <cstdlib>

using namespace std;

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

     JavaVMInitArgs vm_args;
     JavaVMOption* options = new JavaVMOption[1]; //LINE 18 ERROR
     options[0].optionString = 
           (char*)&"-Djava.class.path=C:\\Program Files\\Java\\jdk1.7.0\\bin";
     vm_args.version = JNI_VERSION_1_6;
     vm_args.nOptions = 1;
     vm_args.options = options;
     vm_args.ignoreUnrecognized = false;

     /* load and initialize a Java VM, return a JNI interface
      * pointer in env */
     res = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); //LINE 26 ERROR

     if (res < 0) 
       {
         fprintf(stderr, "Can't create Java VM\n");
         exit(1);
       }
     cls = env->FindClass("TestJNIInvoke");
     if (cls == NULL) 
       {
         goto destroy;
       }

     mid = env->GetStaticMethodID(cls, "main",
                  "([Ljava/lang/String;)V");
     if (mid == NULL) 
       {
         goto destroy;
       }
     jstr = env->NewStringUTF(" from CPP!");
     if (jstr == NULL) 
       {
         goto destroy;
       }
     stringClass = env->FindClass("java/lang/String");
     args = env->NewObjectArray(1, stringClass, jstr);
     if (args == NULL) 
       {
         goto destroy;
       }
     env->CallStaticVoidMethod(cls, mid, args);

 destroy:
     if (env->ExceptionOccurred()) 
       {
          env->ExceptionDescribe();
       }
     jvm->DestroyJavaVM();
}

Anyway If I just compile the file with:

gcc -I"c:\Program Files\Java\jdk1.7.0\include" 
    -I"c:\Program Files\Java\jdk1.7.0\include\win32" -c TestJNIInvoke.cpp

It compiles fine, but when I try to compile and link:

gcc -I"c:\Program Files\Java\jdk1.7.0\include" 
    -I"c:\Program Files\Java\jdk1.7.0\include\win32" -g TestJNIInvoke.cpp

I get two weird errors that I don't understand:

TestJNIInvoke.cpp:18: undefined reference to `operator new[](unsigned int)'
TestJNIInvoke.cpp:26: undefined reference to `_imp__JNI_CreateJavaVM@12'
collect2: ld returned 1 exit status

I marked the lines in the above code where the error is occuring, has anyone encountered this problem before?

Any ideas/links would be great

Thanks

Upvotes: 4

Views: 2506

Answers (1)

CurtisB
CurtisB

Reputation: 224

First, don't use gcc. By default, it assumes the code it's handling is written in C. When you want it to compile or link C++ code, you should run g++. This will bring in the C++ standard headers and libraries.

Second, you need to include the java libraries. Section 7.2.1 in the page you linked discusses this.

Your command line should look more like this:

g++ -I"C:\Program Files\Java\jdk1.7.0\include" -L"C:\Program Files\Java\jdk1.7.0\lib" -lthread -ljava TestJNIInvoke.cpp

Note that you might have to add additional include (-I) or linker (-L) directories.

Upvotes: 6

Related Questions