Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Constructing an object crashes jvm

Constructing an object crashes the jvm because the constructor is not found. The signature is correct and the constructor exists.
This is my new object code:

JavaObject(jclass klass, const char *signature, ...) {
    std::cout << "constructing" << std::endl;
    va_list arg;
    va_start(arg, signature);
        
    jmethodID constructor = client->env->GetMethodID(klass, "<init>", signature);
    jobject newObject = client->env->NewObjectV(klass, constructor, arg);
    this->object = &newObject;
    va_end(arg);
}

And then:

// javaClass->getClass() is java.lang.String
String(jcharArray v1) : JavaObject(javaClass->getClass(), "([C)V", v1) {}

edit: my class is java.lang.String. It has the constructor String(char[]). Running javap -s gives me the signature.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

You can never directly access the va_list value. You must call va_arg on it to get the arguments. va_list does not contain the first argument; it contains an unspecified type which can access the first argument by means of va_arg.

jobject newObject = client->env->NewObjectV(klass, constructor, va_arg(arg, ExpectedType));

But this is all academic, because we’re in C++ in 2023, not C in 1991. There’s no compelling reason to use va_list at all anymore; it’s just a less type-safe version of variadic parameter packs. Your signature should look something like

template <typename... Ts>
JavaObject(jclass klass, const char *signature, const Ts&... args)

To use args (which is now type-safe), you can expand it in another argument list as

client->env->NewObjectV(klass, constructor, args...);

You can use it in a std::tuple or other type that expects parameter packs, to perform runtime operations on the pack as a single data structure.

auto my_args = std::make_tuple(args...);

You can’t invoke undefined behavior by using parameter packs with the wrong types, as you’ll just get a compiler error rather than the runtime just dying in exciting ways.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading