I have some issue embedding the JVM in my C/++ program.
Startup and everything else seems to be fine, but, when I close a simple JVM with DestroyJavaVM()
I get an error.
This error means that successive openings don't operate correctly - so - I need to fix it.
I'm installing another JVM to see if it's just OpenJ9 but that seems likely.
Attached is an example using the "Catch" header that does/should compile with only the jni headers and run if JAVA_HOME
points correctly on Windows.
edited to include Remy Lebeau's advice
// https://github.com/catchorg/Catch2/tree/Catch1.x
// https://github.com/philsquared/Catch/releases/download/v1.12.2/catch.hpp
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#pragma once
#pragma warning( push )
#pragma warning( suppress : 26451 )
#pragma warning( suppress : 26495 )
#pragma warning( suppress : 26812 )
#include <jni.h>
#pragma warning( pop )
using create_java_vm_t = jint(JNICALL*)(JavaVM**, void**, void*);
TEST_CASE("a minimum example for the internet", "[paljni]")
{
// taken from
// https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp9502
//
/// (this works fine)
// find the jvm functions - this works fine
static create_java_vm_t create_java_vm = nullptr;
if (!create_java_vm)
{
auto path = std::string(getenv("JAVA_HOME")) + "bin/default/jvm.dll";
auto dll = LoadLibrary(path.c_str());
REQUIRE(dll);
create_java_vm = reinterpret_cast<create_java_vm_t>(GetProcAddress(dll, "JNI_CreateJavaVM"));
REQUIRE(nullptr != create_java_vm);
}
/// (this works fine)
// compute the args
JavaVMInitArgs args = {};
args.version = JNI_VERSION_1_6;
std::vector<JavaVMOption>options;
// options.emplace(options.end())->optionString = "-verbose:jni";
options.emplace(options.end())->optionString = "-verbose:init"; // shows a lot of status messages that seem to suggest all threads close fine
// options.emplace(options.end())->optionString = "-Xcheck:jni:warn";
// options.emplace(options.end())->optionString = "-Xcheck:jni:advice";
// options.emplace(options.end())->optionString = "-Xcheck:jni:pedantic";
args.options = options.data();
args.nOptions = options.size();
/// (this works fine)
// create the vm
JavaVM* jvm;
JNIEnv* env;
const auto create_ret = create_java_vm(&jvm, (void**)&env, &args);
REQUIRE(JNI_OK == create_ret);
///
// clean up the vm
//
// THIS DOES NOT WORK! IT RETURNS (-1)
//
const auto done = jvm->DestroyJavaVM();
REQUIRE(JNI_OK == done);
FAIL("The test doesn't reach this point");
}