error while loading shared libraries: jvm.dll - c++

I am trying to run a java program using c++ code. I tried below code
#include<jni.h>
#include<stdio.h>
int main(int argc, char** argv) {
JavaVM* vm;
JNIEnv* env;
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = 1;
// Construct a VM
jint results = JNI_CreateJavaVM(&vm, (void**)& env, &vm_args);
// Construct a String
jstring jstr = env->NewStringUTF("Hello World");
// First get the class that contains the method you need to call
jclass clazz = env->FindClass("java/lang/String");
// Get the method that you want to call
jmethodID to_lower = env->GetMethodID(clazz, "toLowerCase",
"()Ljava/lang/String;");
// Call the method on the object
jobject result = env->CallObjectMethod(jstr, to_lower);
// Get a C-style string
const char* str = env->GetStringUTFChars((jstring)result, NULL);
printf("%s\n", str);
// Clean up
env->ReleaseStringUTFChars(jstr, str);
// Shutdown the VM.
vm->DestroyJavaVM();
}
I used below command to compile the code
g++ LoadJVM.c -I/c/apps64/Java/jdk-11.0.1/include -I/c/apps64/Java/jdk-11.0.1/include/win32 -L/c/apps64/Java/jdk-11.0.1/lib/ -ljvm
It compiles fine, but when i run the executable like below, i am facing error
./a.exe
Error
error while loading shared libraries: jvm.dll: cannot open shared object file: No such file or directory
Any Idea why this jvm.dll is not getting loaded?
PS: I am compiling and running from Git-Bash on windows 10.

It looks like your jvm.dll can not be found.
Let's say we have 32bit MinGW installation (this is the version I have).
simple.cc
#include<jni.h>
#include<stdio.h>
int main(int argc, char** argv) {
JavaVM* vm;
JNIEnv* env;
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 0;
vm_args.ignoreUnrecognized = 1;
// Construct a VM
jint results = JNI_CreateJavaVM(&vm, (void**)& env, &vm_args);
printf("Hello");
// Shutdown the VM.
(*vm).DestroyJavaVM();
}
compilation and execution
> export JAVA_HOME="/c/Program\ Files\ \(x86\)/Java/jdk1.8.0_211/"
> export PATH="/c/Program Files (x86)/Java/jdk1.8.0_211/jre/bin/server/":"$PATH"
> g++ -o simple simple.cc -I"$JAVA_HOME/include/" -I"$JAVA_HOME/include/win32/" -L"$JAVA_HOME/lib" -ljvm
> ./simple
Hello
you have to make sure that jvm.dll is visible on %PATH% - $PATH inside git-bash.

Related

V8 compile samples/hello-world.cc on Ubuntu

Trying to compile V8 samples/hello-world.cc on ubuntu
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include/libplatform/libplatform.h"
#include "include/v8.h"
int main(int argc, char* argv[]) {
// Initialize V8.
v8::V8::InitializeICUDefaultLocation(argv[0]);
v8::V8::InitializeExternalStartupData(argv[0]);
std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
v8::V8::InitializePlatform(platform.get());
v8::V8::Initialize();
// Create a new Isolate and make it the current one.
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator =
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
v8::Isolate* isolate = v8::Isolate::New(create_params);
{
v8::Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
v8::HandleScope handle_scope(isolate);
// Create a new context.
v8::Local<v8::Context> context = v8::Context::New(isolate);
// Enter the context for compiling and running the hello world script.
v8::Context::Scope context_scope(context);
// Create a string containing the JavaScript source code.
v8::Local<v8::String> source =
v8::String::NewFromUtf8(isolate, "'Hello' + ', World!'",
v8::NewStringType::kNormal)
.ToLocalChecked();
// Compile the source code.
v8::Local<v8::Script> script =
v8::Script::Compile(context, source).ToLocalChecked();
// Run the script to get the result.
v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
// Convert the result to an UTF8 string and print it.
v8::String::Utf8Value utf8(isolate, result);
printf("%s\n", *utf8);
}
// Dispose the isolate and tear down V8.
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
delete create_params.array_buffer_allocator;
return 0;
}
with following command:
g++ -I. -Iinclude samples/hello-world.cc -o hello-world -Wl,--start-group \
out.gn/x64.release/libicui18n.so out.gn/x64.release/libicuuc.so\
out.gn/x64.release/libv8_libbase.so\
out.gn/x64.release/libv8_libplatform.so\ out.gn/x64.release/libv8.so\
out.gn/x64.release/libc++.so\
-Wl,--end-group -lrt -ldl -pthread -std=c++0x
And getting an Error:
hello-world.cc:(.text+0x75): undefined reference to
v8::platform::NewDefaultPlatform(int, v8::platform::IdleTaskSupport,
v8::platform::InProcessStackDumping,
std::unique_ptr<v8::TracingController,
std::default_delete<v8::TracingController> >)
Note that I built V8 with GN args:
"is_debug = false, is_official_build = true, is_component_build = true, is_cfi = false, is_clang = false, v8_use_external_startup_data = false, treat_warnings_as_errors = false, use_custom_libcxx = false, use_sysroot = false, use_gold = false"
Am I doing something wrong with V8 built or compilation of samples/hello-world.cc
In your compiler command line, try removing the \ after out.gn/x64.release/libv8_libplatform.so. \ is an "escape" character, so it changes how the following space is interpreted -- specifically, it makes it part of the file name rather than a file name separator, resulting in a filename that does not exist.
Does that help?

V8 - C++ binding : How to return v8 compiled script from c++ function and Run it in other function

I am currently working on ubuntu 12.04 . I have simple hello world program in c++ with v8 binding as follows :
#include "include/v8.h"
#include "include/libplatform/libplatform.h"
using namespace v8;
int main(int argc, char* argv[]) {
// Initialize V8.
V8::InitializeICU();
Platform* platform = platform::CreateDefaultPlatform();
V8::InitializePlatform(platform);
V8::Initialize();
// Create a new Isolate and make it the current one.
//Isolate* isolate = Isolate::GetCurrent();
Isolate* isolate = Isolate::New();
{
Isolate::Scope isolate_scope(isolate);
// Create a stack-allocated handle scope.
HandleScope handle_scope(isolate);
// Create a new context.
Local<Context> context = Context::New(isolate);
// Enter the context for compiling and running the hello world script.
Context::Scope context_scope(context);
// Create a string containing the JavaScript source code.
Local<String> source = String::NewFromUtf8(isolate, "'Hello' + ', World!'");
// Compile the source code.
Local<Script> script = Script::Compile(source);
// Run the script to get the result.
Local<Value> result = script->Run();
// Convert the result to an UTF8 string and print it.
String::Utf8Value utf8(result);
printf("%s\n", *utf8);
}
// Dispose the isolate and tear down V8.
isolate->Dispose();
V8::Dispose();
V8::ShutdownPlatform();
delete platform;
return 0;
}
I just want
compilation( Local<Script> script = Script::Compile(source);)
and
execution(Local<Value> result = script->Run();)
in different functions. Is it possible? if yes , how? Can anybody help

Undefined Reference to JNI_CreateJavaVM Eclipse and Linux

I am using Ubuntu 10.04 with Omnet++ 4.0p1 and JSimpleModule (which uses SWIG to make Java wrappers for the C++ methods found in Omnet++). I am trying to create a simulation in Java using the 2 above libraries, and when I am trying to build the project I am getting 'Undefined Reference to JNI_CreateJavaVM' as an error in JUtil.cc (which is code supplied by JSimpleModule). I have been looking around and I am including all of the proper libraries and it still isn't fixing anything. In the Omnet++ IDE (Eclipse) I am including:
/usr/lib/jvm/java-6-openjdk/include
/usr/lib/jvm/java-6-openjdk/include/linux
/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client
and am linking:
/usr/lib/jvm/java-6-openjdk/jre/lib
/usr/lib/jvm/java-6-openjdk/jre/lib/client
-ljvm
I also tried compiling from the terminal using opp_makemake (which creates a Makefile) with the following parameters:
-I/usr/lib/jvm/java-6-openjdk/include
-I/usr/lib/jvm/java-6-openjdk/include/linux
-I/usr/lib/jvm/java-6-openjdk/jre/lib/i386/client
-L/usr/lib/jvm/java-6-openjdk/jre/lib
-L/usr/lib/jvm/java-6-openjdk/jre/lib/client -ljvm
Here is the beginning of JUtil.cc up to the error (note: jni.h is included in JUtil.h):
#include "JUtil.h"
#include "JSimpleModule.h"
//#define DEBUGPRINTF printf
#define DEBUGPRINTF (void)
#ifdef _WIN32
#define PATH_SEP ";"
#else
#define PATH_SEP ":"
#endif
// This will come from the generated SimkernelJNI_registerNatives.cc
void SimkernelJNI_registerNatives(JNIEnv *jenv);
JavaVM *JUtil::vm;
JNIEnv *JUtil::jenv;
void JUtil::initJVM()
{
DEBUGPRINTF("Starting JVM...\n");
JavaVMInitArgs vm_args;
JavaVMOption options[10];
int n = 0;
const char *classpath = getenv("CLASSPATH");
if (!classpath)
opp_error("CLASSPATH environment variable is not set");
// FIXME remove hack once IDE builds the classpath corretcly
const char *classpath2 = getenv("CLASSPATH2");
std::string classpathOption = std::string("-Djava.class.path=")+(classpath2 ? classpath2 : "")+PATH_SEP+(classpath ? classpath : "");
options[n++].optionString = (char *)classpathOption.c_str(); /* user classes */
options[n++].optionString = (char *)"-Djava.library.path=."; /* set native library path */
//options[n++].optionString = "-Djava.compiler=NONE"; /* disable JIT */
//options[n++].optionString = "-verbose:jni"; /* print JNI-related messages */
//options[n++].optionString = "-verbose:class"; /* print class loading messages */
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = n;
vm_args.ignoreUnrecognized = true;
int res = JNI_CreateJavaVM(&vm, (void **)&jenv, &vm_args);
if (res<0)
opp_error("Could not create Java VM: JNI_CreateJavaVM returned %d", res);
DEBUGPRINTF("Registering native methods...\n");
SimkernelJNI_registerNatives(jenv);
DEBUGPRINTF("Done.\n");
}
If someone knows anything on how to fix this, that would be greatly appreciated. Thanks.

boost test case from dll access violation

I want to start Boost test case from dll under Windows RT. I built test case as dll via the Visual Studio command prompt using the following comandline:
cl.exe /EHsc /D_USRDLL /D_WINDLL /LDd ~location\testcase.cpp ~library location\libboost_unit_test_framework-vc110-mt-sgd-1_53.lib /link /DLL /OUT:~output directory\testcase.dll
placed it into my application’s folder and set property "Content" to "true". After launching of my application I have the following error:
Unhadled exception at the 0x00B9AF16 in TestApp.exe: 0xC0000005: Access violation reading location 0x00000000
Top of the call stack is below:
> TestApp.exe!boost::unit_test::framework::get(unsigned long id, boost::unit_test::test_unit_type t) Line 388 C++
TestApp.exe!boost::unit_test::framework::get(unsigned long id) Line 73 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 232 C++
TestApp.exe!boost::unit_test::traverse_test_tree(const boost::unit_test::test_suite & suite, boost::unit_test::test_tree_visitor & V) Line 207 C++
TestApp.exe!boost::unit_test::traverse_test_tree(unsigned long id, boost::unit_test::test_tree_visitor & V) Line 234 C++
TestApp.exe!boost::unit_test::framework::run(unsigned long id, bool continue_test) Line 403 C++
TestApp.exe!boost::unit_test::unit_test_main(boost::unit_test::test_suite * (int, char * *) * init_func, int argc, char * * argv) Line 185 C++
Here is the dll code (NOTE: If I place the same code directly into my source, it works fine):
void test_stat()
{
//some code there
}
extern "C" {
__declspec (dllexport) test_suite* init_unit_test_suite( int argc, char* argv[] )
{
test_suite *test = BOOST_TEST_SUITE("test name");
test->add(BOOST_TEST_CASE(&test_stat));
return test;
}
}
Code of the application for launching of the test case:
boost::unit_test::test_suite* main_global_test_suite;
test_suite* init_unit_test_suite( int argc, char* argv[] ) {
return NULL; }
test_suite* run_global_test_suite (int, char* []) {
return main_global_test_suite;
}
HINSTANCE hMyDll;
typedef test_suite* (*PFN_MyFunction)(int,const char*);
PFN_MyFunction pfnMyFunction;
test_suite* rPtr;
if((hMyDll=::LoadPackagedLibrary(L"testcase", 0))==NULL)
{
return;
}
pfnMyFunction=(PFN_MyFunction)GetProcAddress(hMyDll,"init_unit_test_suite");
if (pfnMyFunction != NULL)
{
//just create fake arguments for the boost::unit_test::unit_test_main function call
char* argv[1024];
argv[0] = "Text";
rPtr = pfnMyFunction(1, NULL);
main_global_test_suite = rPtr;
const int error =
boost::unit_test::unit_test_main(&run_global_test_suite, 1, argv );
}
else
{
//handling code
}
FreeLibrary(hMyDll);
Is there any ideas how to solve the problem?
Check what console_test_runner is doing. This is command line application (part of Boost.Test), which intended to do just that - load and execute test units implemented in shared library. Also please make sure you tell UTF that you want to build dll: define BOOST_TEST_DYN_LINK.

Segmentation fault in v8 hello world when using TryCatch

I am trying to use v8 in my C++ application. I am stuck on the helloworld itself!
The helloworld at https://developers.google.com/v8/get_started works just fine. Now I am trying to catch exceptions/error in the code. So I used TryCatch trycatch;.
int main(int argc, char *argv[]) {
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
TryCatch trycatch; /* TO CATCH EXCETIONS/ERRORS */
Handle<String> source = String::New("xyz();");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
if (result.IsEmpty()) {
fprintf(stderr, "Exception: %s\n",
*String::AsciiValue(trycatch.Exception()));
return -1;
}
String::AsciiValue ascii(result);
printf("%s\n", *ascii);
context.Dispose();
return 0;
}
The exceptions are caught fine but the program does not terminate properly. It generates a segmentation fault. What am I doing wrong?
Turned out to be a foolish thing. I had long back installed libv8-dev and forgotten about it. And now I installed V8 from source. So I had two versions of V8 on my system. I uninstalled libv8-dev and the problem has been solved.