0

I'm trying to use a rather complex Java program within a C++ program. Let me make clear that I don't know much about Java, so I hope I won't be overinterpreting or speaking nonsense about Java.

For my purpose I'm using JNI. Creation of the JVM works fine, and I've been able to successfully call simple classes in a C++ program, i.e. single java files compiled to classes, contained in the same directory as my cpp, with no dependencies.

Now, I'm willing to call methods from a Java program which 1. is part of a package, 2. has a lot of dependencies outside of the package, 3. does not have a main.

My idea was to first, within Eclipse, build a "runnable jar" of the package from which I want to call methods, assuming it would include the external dependencies.

I don't quite know how a jar works, so I may be wrong in that, or have made mistakes in the process. I may be proceeding in a way does not actually include all dependencies? this is my current hypothesis, but I how could I check and get more details than what the exception shown below tells me? I also assume it's okay that the package I want to use classes from has no main, because ultimately I just want to use one method, but I may be wrong here too.

So I added the path of this jar to the classpath as seen from C++ :

options[0].optionString = "-Djava.class.path=C:\\Users\\anker\\source\\repos\\mc_solver\\target\jars\\package_name.jar";

he program goes as follows :

...
    JavaVM *jvm;                    
    JNIEnv *env;                      

    JavaVMInitArgs vm_args;                        
    JavaVMOption* options = new JavaVMOption[1];  
    options[0].optionString = "-Djava.class.path=C:\\Users\\anker\\source\\repos\\mc_solver\\target\jars\\package_name.jar";
    vm_args.version = JNI_VERSION_1_8; 
    vm_args.nOptions = 1;               
    vm_args.options = options;
    vm_args.ignoreUnrecognized = false;    
    jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);  
    delete options;    // 
    if (rc != JNI_OK) {
        cin.get();
        exit(EXIT_FAILURE);
    }
    //=============== Display JVM version =======================================
    cout << "JVM load succeeded: Version ";
    jint ver = env->GetVersion();
    cout << ((ver >> 16) & 0x0f) << "." << (ver & 0x0f) << endl;

    jclass cls2 = env->FindClass("package_name/class_name"); 
    if (cls2 == nullptr) {
        if (env->ExceptionOccurred()) {
            env->ExceptionDescribe();
        }
        cerr << "ERROR: class not found !";
    }
...

And env->ExceptionDescribe(); tells me the following :

Exception in thread "main" java.lang.NoClassDefFoundError: package_name/class_name
Caused by: java.lang.ClassNotFoundException: package_name.class_name
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)

Thank you very much for your attention, what would you advise ?

anton_k
  • 1
  • 1
  • maybe it a duplicated question: https://stackoverflow.com/questions/1611357/how-to-make-a-jar-file-that-includes-dll-files – Gulyás István Dec 16 '20 at 16:08
  • 1
    There's an unescaped backslash in your option string. As this is Java, just using forward slashes will make it more readable. – user2543253 Dec 16 '20 at 16:17
  • @user2543253 thanks for this remark, I corrected it, however it did not change the output. – anton_k Dec 16 '20 at 16:22
  • @GulyásIstván thanks for the reference. I'm not sure it's related, except it deals with nested jars. What I tried to do is develop all jars contained in the main jar I created manually (wasn't that deep). Having checked I think I'm confident all dependencies were indeed contained in it, since all external dependencies I know of are. I replaced the classpath to the path of the unzipped folder. I get the exact same error. – anton_k Dec 16 '20 at 16:41

0 Answers0