Search code examples
javac++jarjava-native-interface

Find Java class in .jar using JNI


I'm writing a program where I call Java functions from C++ code using JNI. My program runs fine if I use .class file directly, but when I add it to a jar file FindClass fails. For example this works fine

    std::string stdOpt = "-Djava.class.path=<path_to_jar>/dependency.jar;<path_to_class>";

    boost::scoped_array<char> opt(new char[stdOpt.size() + 1]);
    std::copy(stdOpt.begin(), stdOpt.end(), opt.get());
    opt[stdOpt.size()] = '\0';
    options[0].optionString = opt.get();

    JavaVMInitArgs vm_args;
    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    long status = JNI_CreateJavaVM(&m_pJavaVirtualMachine, (void**)&m_pJavaEnvironment, &vm_args);
    if (status != JNI_OK)
        throw std::logic_error("Cannot start Java Virtual Machine");

    m_class = m_pJavaEnvironment->FindClass("MyClass");
    if(m_class == 0)
        throw std::logic_error("Cannot find Java class");

But this one fails

    std::string stdOpt = "-Djava.class.path=<path_to_jar>/dependency.jar;<path_to_jar>/myjar.jar";

    boost::scoped_array<char> opt(new char[stdOpt.size() + 1]);
    std::copy(stdOpt.begin(), stdOpt.end(), opt.get());
    opt[stdOpt.size()] = '\0';
    options[0].optionString = opt.get();

    JavaVMInitArgs vm_args;
    memset(&vm_args, 0, sizeof(vm_args));
    vm_args.version = JNI_VERSION_1_6;
    vm_args.nOptions = 1;
    vm_args.options = options;
    long status = JNI_CreateJavaVM(&m_pJavaVirtualMachine, (void**)&m_pJavaEnvironment, &vm_args);
    if (status != JNI_OK)
        throw std::logic_error("Cannot start Java Virtual Machine");

    m_class = m_pJavaEnvironment->FindClass("MyClass");    //m_class=NULL
    if(m_class == 0)
        throw std::logic_error("Cannot find Java class");  //throwing exception 

Is there any difference that I should do when I'm trying to get Java class from .jar? What's Wrong? Any ideas?


Solution

  • It turned out, that problem was not in code. Code is fine. Problem was in making .jar file. I'm using Visual Studio and for auto compilation .java to .class and addition .class to a .jar file I've added to pre-build events to project. So before making .jar file I should specify current directory like this

    cd "<_directory_where_.class_file_is_located>"

    jar cf myjar.jar MyClass.class

    Otherwise MyClass.class was added to .jar file with folders of it's absolute path and FindClass() failed.