Undefined Reference to JNI_CreateJavaVM Eclipse and Linux - java-native-interface

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.

Related

Why does my DLL load properly when given an absolute path but not a relative path?

I have created a simple dll using /MDd flag on windows 10 using msvc 2019 compilers. The dll only contains a simple add function (like in all the tutorials). After building this library I've copied it into a test folder for explicit linking. Basically, the test passes if I give it the full absolute path to the dll but it doesn't load if I only provide the name of the dll.
Here is the test code:
//test_add.cpp
#include <windows.h>
#include "gtest/gtest.h"
TEST(test, test_add_windows) {
#if defined(_WIN32) || defined (_WIN64)
typedef int (*addPtr)(int, int);
// full path works and the test passes
HINSTANCE hinstLib = LoadLibrary(TEXT("D:\\ACrossPlatformCppLibrary\\test\\ACrossPlatformCppLibrary.dll"));
// relative path does not work: library fails to load
// HINSTANCE hinstLib = LoadLibrary(TEXT("ACrossPlatformCppLibrary.dll"));
std::cout << hinstLib << std::endl;
ASSERT_NE(hinstLib, nullptr);
auto add = (addPtr) GetProcAddress(hinstLib, "add");
ASSERT_NE(add, nullptr);
int x = 5;
int y = 6;
int answer = add(x, y);
ASSERT_EQ(answer, 11);
BOOL fFreeResult = FreeLibrary(hinstLib);
#else
ASSERT_TRUE(true);
#endif
}
And my directory tree
I figured out the answer. I ran another test from the same file to get the current directory:
TEST(test, test2) {
char *fileExt;
char szDir[256]; //dummy buffer
GetFullPathName(".", 256, szDir, &fileExt);
printf("Full path: %s\nFilename: %s", szDir, fileExt);
}
Which outputs:
Full path: D:\ACrossPlatformCppLibrary\cmake-build-debug\test
The problem was that I copied the dll into the source directory, not the build directory.

undefined reference to `pthread_create' on Yocto plugin on Eclipse IDE on Ubuntu

I am doing a cross compilation test in Eclipse IDE for meta-toolchain made with Yocto, for arm cortex A9 processor. After performing hello world test, which ran successfully, I created a basic program to test pthreads.
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#define MILLION 1000000 /* one million = 10^6*/
#define sec_to_nsec 1000000000 /* ns to s conversion = 10^9 */
#define FILENAME "Schd.txt"
#define FLUSH_TIME 10.0
#define SIG_LLP_TIMER SIGRTMIN+1
int isr_idx; /* counter of ISR occurred -- starts from 0 and increments at each interrupt*/
volatile float clk_k, /* MY_CLOCK() value for the current sample*/
clk_k_1; /* MY_CLOCK() value for the previous sample*/
/*clock and timer values*/
struct itimerspec custom_itimerspec;
timer_t timer_id;
clockid_t USED_CLK;
struct timespec tv;
float a_n;
/*THREAD DATA*/
pthread_t thread0;
pthread_attr_t attr;
struct sched_param param;
using namespace std;
void* thread_scheduler(){
//function pointer
//mainThread
//make thread for scheduling
//exit after max cycle
}
int main(void)
{
cout << "Starting the program!" << endl; /* prints Hello World */
cout<< "Creating a Thread to deploy" << endl;
int status;
param.__sched_priority = 99;
int retc;
/*PTHREAD ATTR setup*/
retc = pthread_attr_init(&attr);
retc |= pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
retc |= pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
retc |= pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
retc |= pthread_attr_setschedparam(&attr,&param);
if (retc != 0) {
//fail
while(1){}
}
retc = pthread_create(&thread0, &attr, (void * (*)(void *))thread_scheduler, NULL);
printf("Exiting here!");
return 0;
}
But I get this error, undefined reference to `pthread_create', followed with some make errors.
Though after doing some search I found that adding '-pthread' command in configure and autogen settings works for building the project, as described here. But I am puzzled why the compiler can't see these files even if this file is present in 'includes' in the drop down folder of project explorer.
The error about undefined reference is coming from linking step, not from compiling and assembling step, compile step would look for header files and its rightly finding the pthread.h from sysroot include directory as you see as well. After compiling, it has to invoke the linker to create the executable binary and thats where it fails.
When linking it need to add libpthread to linker commandline so linker can find the pthread_create function and link it into final executable, this is usually done via specifying LDFLAGS which then get appended to linker invocation.
compiler driver ( gcc ) can be used to drive both compiling and linking steps.
so when you add -pthread option to compiler and compiler is also used to perform linking then it translates this option into -lpthread to linker cmdline which would then find libpthread and link it in.

fatal error: strtok_r.h: No such file or directory (while compiling tesseract-ocr-3.01 in MinGW)

I'm compiling tesseract-ocr-3.01 in MinGW, and I'm getting this error ambigs.cpp:31:22: fatal error: strtok_r.h: No such file or directory
This is the code where the error is:
#ifdef WIN32
#ifndef __GNUC__
#define strtok_r strtok_s
#else
#include "strtok_r.h"
#endif /* __GNUC__ */
#endif /* WIN32 */
Edit
I found this feature request to add strtok_r.h to MinGW. From the comments there:
strtok_r() is an optional POSIX function, required only for
implementations which support POSIX threads. MinGW does not support
POSIX threads; therefore, I don't think that this function has any
place in a base MinGW distribution.
POSIX threads support for MS-Windows is provided by the pthreads-win32
project. Maybe they already provide a strtok_r() implementation. If
so, then you could use it; if not, you might ask them to consider
adding it.
The problem is most easily solved by adding an strtok_r implementation to the project's sources:
char *strtok_r(char *str, const char *delim, char **save)
{
char *res, *last;
if( !save )
return strtok(str, delim);
if( !str && !(str = *save) )
return NULL;
last = str + strlen(str);
if( (*save = res = strtok(str, delim)) )
{
*save += strlen(res);
if( *save < last )
(*save)++;
else
*save = NULL;
}
return res;
}

Can't make call from C++ To Java using JNI

I have a little project with cocos2d-x libraries. I'm trying to use C++ to call a Java function but i get a signal 11 exception at line:
// Get Status
status = jvm->GetEnv((void **) &env, JNI_VERSION_1_6);
But i don't know why this is happening.
In my Java class Getsocial.java exist this function:
private void tweet()
{
String score = "123";
String tweetUrl = "https://twitter.com/intent/tweet?text=Hello ! I have just got " + score + " points in mygame for Android !!!!";
Uri uri = Uri.parse(tweetUrl);
startActivity(new Intent(Intent.ACTION_VIEW, uri));
}
This function launch navigator to post a tweet. Called from Java works fine.
In my C++ InterfaceJNI.h I have:
#ifndef __INTERFACE_JNI_H__
#define __INTERFACE_JNI_H__
#include "cocos2d.h"
class InterfaceJNI
{
public:
static void postMessageToFB();
static void postMessageToTweet();
protected:
};
#endif // __INTERFACE_JNI_H__
And in InterfaceJNI.cpp:
#include "InterfaceJNI.h"
#include "platform/android/jni/JniHelper.h"
#include jni.h >
#include android/log.h >
using namespace cocos2d;
void InterfaceJNI::postMessageToTweet()
{
int status;
JNIEnv *env;
JavaVM *jvm;
jmethodID mid;
jclass mClass;
bool isAttached = false;
CCLog("Static postMessageToTweet");
// Get Status
status = jvm->GetEnv((void **) &env, JNI_VERSION_1_6);
CCLog("Status: %d", status);
if(status AttachCurrentThread(&env, NULL);
CCLog("Status 2: %d", status);
if(status GetStaticMethodID(mClass, "tweet", "()V");
CCLog("mID: %d", mid);
if (mid!=0)
env->CallStaticVoidMethod(mClass, mid);
//-----------------------------------------------------------
CCLog("Finish");
if(isAttached)
jvm->DetachCurrentThread();
return;
}
This interface is called from a part of the code using:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
InterfaceJNI::postMessageToTweet();
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
ObjCCalls::trySendATweet();
#endif
What is happening to return a null pointer on jvm->GetEnv((void **) &env, JNI_VERSION_1_6); ?
It looks like your jvm variable is null or garbage. The version of Cocos2D-x I use has a class called JniHelper with a static ::getJavaVM(); method that you might want to use.
JavaVM* vm = JniHelper::getJavaVM();
JNIEnv* env;
vm->GetEnv((void**)&env,JNI_VERSION_1_4); // mine uses JNI_VERSION_1_4
Also, remember to "refresh" your eclipse project every time you build with NDK. You probably do already, but it's worth checking.

Weird and unpredictable crash when using libx264 cross-compiled with MinGW

I'm working on a C++ project using Visual Studio 2010 on Windows. I'm linking dynamically against x264 which I built myself as a shared library using MinGW following the guide at
http://www.ayobamiadewole.com/Blog/Others/x264compilation.aspx
The strange thing is that my x264 code is working perfectly sometimes. Then when I change some line of code (or even change the comments in the file!) and recompile everything crashes on the line
encoder_ = x264_encoder_open(&param);
With the message
Access violation reading location 0x00000000
I'm not doing anything funky at all so it's probably not my code that is wrong but I guess there is something going wrong with the linking or maybe something is wrong with how I compiled x264.
The full initialization code:
x264_param_t param = { 0 };
if (x264_param_default_preset(&param, "ultrafast", "zerolatency") < 0) {
throw KStreamerException("x264_param_default_preset failed");
}
param.i_threads = 1;
param.i_width = 640;
param.i_height = 480;
param.i_fps_num = 10;
param.i_fps_den = 1;
encoder_ = x264_encoder_open(&param); // <-----
if (encoder_ == 0) {
throw KStreamerException("x264_encoder_open failed");
}
x264_picture_alloc(&pic_, X264_CSP_I420, 640, 480);
Edit: It turns out that it always works in Release mode and when using superfast instead of ultrafast it also works in Debug mode 100%. Could it be that the ultrafast mode is doing some crazy optimizations that the debugger doesn't like?
I've met this problem too with libx264-120.
libx264-120 was built on MinGW and configuration option like below.
$ ./configure --disable-cli --enable-shared --extra-ldflags=-Wl,--output-def=libx264-120.def --enable-debug --enable-win32thread
platform: X86
system: WINDOWS
cli: no
libx264: internal
shared: yes
static: no
asm: yes
interlaced: yes
avs: yes
lavf: no
ffms: no
gpac: no
gpl: yes
thread: win32
filters: crop select_every
debug: yes
gprof: no
strip: no
PIC: no
visualize: no
bit depth: 8
chroma format: all
$ make -j8
lib /def:libx264-120.def /machine:x86
#include "stdafx.h"
#include <iostream>
#include <cassert>
using namespace std;
#include <stdint.h>
extern "C"{
#include <x264.h>
}
int _tmain(int argc, _TCHAR* argv[])
{
int width(640);
int height(480);
int err(-1);
x264_param_t x264_param = {0};
//x264_param_default(&x264_param);
err =
x264_param_default_preset(&x264_param, "veryfast", "zerolatency");
assert(0==err);
x264_param.i_threads = 8;
x264_param.i_width = width;
x264_param.i_height = height;
x264_param.i_fps_num = 60;//fps;
x264_param.i_fps_den = 1;
// Intra refres:
x264_param.i_keyint_max = 60;//fps;
x264_param.b_intra_refresh = 1;
//Rate control:
x264_param.rc.i_rc_method = X264_RC_CRF;
x264_param.rc.f_rf_constant = 25;
x264_param.rc.f_rf_constant_max = 35;
//For streaming:
x264_param.b_repeat_headers = 1;
x264_param.b_annexb = 1;
err = x264_param_apply_profile(&x264_param, "baseline");
assert(0==err);
x264_t *x264_encoder = x264_encoder_open(&x264_param);
x264_encoder = x264_encoder;
x264_encoder_close( x264_encoder );
getchar();
return 0;
}
This program succeeds sometime. But will fail often on x264_encoder_open with the access violation.
The information for this is not existing on Google. And how to initialize x264_param_t and how to use x264_encoder_open are unclear.
It seems that behavior caused from x264's setting values, but I can't know these without reading some open source programs that using libx264.
And, this access violation seems doesn't occurs on FIRST TIME EXECUTION and on compilation with MinGW's gcc (e.g gcc -o test test.c -lx264;./test)
Since this behavior, I think that libx264 doing some strange processes of resources in DLL version of ilbx264 that was built on MinGW's gcc.
I had the same problem. The only way I was able to fix it was to build the x264 dll without the asm option (ie. specify --disable-asm)