JNI fatal error when having a package - java

If I put my java files in a package (like jni/test/), I get a fatal error when executing. But if I dont put the files in a package everything work fine.
When having a package:
javac jni/test/Main.java
javah -jni jni.test.Main
g++ -shared -o libfoo.so -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux Main.cpp
java -Djava.library.path=. jni/test/Main
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb6c1ce3c, pid=3704, tid=3060386624
#
# JRE version: 7.0_25-b30
# Java VM: OpenJDK Server VM (23.7-b01 mixed mode linux-x86 )
# Problematic frame:
# V [libjvm.so+0x436e3c] get_method_id(JNIEnv_*, _jclass*, char const*, char const*, bool, Thread*) [clone .isra.106]+0x7c
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/idle/workspace/JNITest/src/hs_err_pid3704.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
# https://bugs.launchpad.net/ubuntu/+source/openjdk-7/
#
Aborted
When not having a package:
javac Main.java
javah -jni Main
g++ -shared -o libfoo.so -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux Main.cpp
java -Djava.library.path=. Main
//This executes fine
I have 2 java classes
public class Animal {
public String name = null;
public int age = 0;
}
public class Main {
public native Animal nativeFoo();
static {
System.loadLibrary("foo");
}
public void print () {
Animal a = nativeFoo();
System.out.println(a.name + " " + a.age);
}
public static void main(String[] args) {
(new Main()).print();
}
}
The c++ part
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Main */
#ifndef _Included_Main
#define _Included_Main
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Main
* Method: nativeFoo
* Signature: ()LAnimal;
*/
//if the java file in a package
//JNIEXPORT jobject JNICALL Java_jni_test_Main_nativeFoo (JNIEnv *env, jobject obxj)
JNIEXPORT jobject JNICALL Java_Main_nativeFoo
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
The cpp file
#include "Main.h"
//if the java file in a package
//JNIEXPORT jobject JNICALL Java_jni_test_Main_nativeFoo (JNIEnv *env, jobject obxj)
JNIEXPORT jobject JNICALL Java_Main_nativeFoo (JNIEnv *env, jobject obxj){
jclass animal = env->FindClass("Animal");
jmethodID cons = env->GetMethodID(animal, "<init>", "()V");
jobject obj = env->NewObject(animal, cons);
jfieldID age = env->GetFieldID(animal, "age", "I");
jfieldID name = env->GetFieldID(animal, "name", "Ljava/lang/String;");
env->SetObjectField(obj, name, env->NewStringUTF("awww"));
env->SetIntField(obj, age, 23);
return obj;
}

Based on the error, which is when get_method_id(JNIEnv_*, _jclass*, char const*, char const*, bool, Thread*) is called via env->GetMethodID(), your jclass variable animal is null.
The FindClass call is failing because it cannot locate the class "Animal".
Validate that your class name and package definition is correct.
See similar question answered here with the same sigsegv

Related

JNI code to return string but gets error java.lang.UnsatisfiedLinkError: com.package.openGeoDb()Ljava/lang/String;

I am deploying a program and encountered error of
Caused by: java.lang.Exception: java.lang.UnsatisfiedLinkError:
com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
I managed to load the dll but I feel like something has caused the string to not be converted correctly and caused the error. The following is the JNI code I am currently testing to deploy on Karaf :
JNI Codes>>>JAVA and c++
JniGeoDbReader.class
package com.package.JniClass;
public final class JniGeoDbReader {
private JniGeoDbReader() { }
public static native String openGeoDb(); }
ServiceClass.class <--- This class is the simplified version
import com.package.JniClass.JniGeoDbReader;
public class ServiceClass{
public void fetchResponse(){
System.load("D:\\DLL_PATH\\com_package_jniGeoDbReader.dll");
LOGGER.info(">>>>>>>>>>>>>>>>> {}", JniGeoDbReader.openGeoDb());
}
}
com_package_JniClass_JniGeoDbReader.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_package_JniClass_JniGeoDbReader */
#ifndef _Included_com_package_JniClass_JniGeoDbReader
#define
_Included_com_package_JniClass_JniGeoDbReader_JniClass_JniGeoDbReader
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_package_JniClass_JniGeoDbReader
* Method: openGeoDb
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_com_package_JniClass_JniGeoDbReader_openGeoDb
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
dllmain.cpp <--I got this code from somewhere else
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "com_package_JniClass_JniGeoDbReader.h"
#include <string>
using namespace std;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
JNIEXPORT jstring JNICALL
Java_com_package_JniClass_JniGeoDbReader_openGeoDb
(JNIEnv *env , jobject obj) {
string message = "Welcome to JNI";
int byteCount = message.length();
const jbyte* pNativeMessage = reinterpret_cast<const jbyte*>
(message.c_str());
jbyteArray bytes = env->NewByteArray(byteCount);
env->SetByteArrayRegion(bytes, 0, byteCount, pNativeMessage);
// find the Charset.forName method:
// javap -s java.nio.charset.Charset | egrep -A2 "forName"
jclass charsetClass = env->FindClass("java/nio/charset/Charset");
jmethodID forName = env->GetStaticMethodID(
charsetClass, "forName", "
(Ljava/lang/String;)Ljava/nio/charset/Charset;");
jstring utf8 = env->NewStringUTF("UTF-8");
jobject charset = env->CallStaticObjectMethod(charsetClass,
forName, utf8);
// find a String constructor that takes a Charset:
// javap -s java.lang.String | egrep -A2 "String\(.*charset"
jclass stringClass = env->FindClass("java/lang/String");
jmethodID ctor = env->GetMethodID(
stringClass, "<init>", "([BLjava/nio/charset/Charset;)V");
jstring jMessage = reinterpret_cast<jstring>(
env->NewObject(stringClass, ctor, bytes, charset));
return jMessage; }
I got the code in the cpp from here: Send C++ string to Java via JNI. I would like to do something similar, that is to return a string without accepting any parameters. But for some reason, it is throwing error. Please guide me in what causes this error and which part of this code I should change. Thank you.
UPDATE
Here is the full stacktrace:
at com.sun.proxy.$Proxy116.fetchCatalogue(Unknown Source)
at com.package.ArcGisDiscoveryJob$CatalogueTask.call(ArcGisDiscoveryJob.java:485)
at com.package.ArcGisDiscoveryJob$CatalogueTask.call(ArcGisDiscoveryJob.java:450)
at com.package.BaseTaskExecutor.invoke(BaseTaskExecutor.java:84)
at com.package.ArcGisDiscoveryJob.traverse(ArcGisDiscoveryJob.java:131)
at com.package.ArcGisDiscoveryJob.run(ArcGisDiscoveryJob.java:224)
at com.package.BaseScheduler$1.run(BaseScheduler.java:101)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.Exception: java.lang.UnsatisfiedLinkError: com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
at com.package.service.rest.impl.ArcGisClientProxy$1.call(ArcGisClientProxy.java:161)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
... 3 more
Caused by: java.lang.UnsatisfiedLinkError: com.package.JniClass.JniGeoDbReader.openGeoDb()Ljava/lang/String;
at com.package.JniClass.JniGeoDbReader.openGeoDb(Native Method)
at com.package.service.rest.impl.ServiceClass.fetchResponse(ServiceClass.java:364)
at com.package.service.rest.impl.ServiceClass.fetchCatalogue(ServiceClass.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.package.service.rest.impl.ArcGisClientProxy.callEndPoint(ArcGisClientProxy.java:241)
at com.package.service.rest.impl.ArcGisClientProxy.access$000(ArcGisClientProxy.java:32)
at com.package.service.rest.impl.ArcGisClientProxy$1.call(ArcGisClientProxy.java:155)
... 4 more
Your header file and your CPP code don't match. The header declares jclass for the second function parameter, but the implementation has jobject. JNI itself would not care because jclass is the same as jobject, but your compiler will not recognize the function, because of the different parameter declaration. Therefore it will not see the extern "C" for the function and export it with CPP name mangling, and Java will not find it.
Edit: hadn't seen #user207421's comment, and while it is important that you always regenerate the header file if something changes in your native method, it won't help in your case because your header already matches the Java code. You also have to change your implementation to match the header.

Java JNI run class from module [duplicate]

I created a C++ class that is supposed to call Main.main by following: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp9502.
I didn't get it to work so I followed: http://www.coderanch.com/t/525082/CPP/create-JVM-native-code-call
and :
imp_JNI_Crea">http://www.codeproject.com/Questions/263687/Linker-error-undefined-reference-to-imp_JNI_Crea
None of which worked. So I changed my code back to what the Invocation API article by oracle says (the first link).
My C++ code looks like:
In JNI.hpp file:
#include <jni.h>
#include <windows.h>
#include <iostream>
class Jvm
{
private:
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs jvm_args;
JavaVMOption* options;
public:
Jvm();
};
In JNI.cpp file:
Jvm::Jvm()
{
options = new JavaVMOption[3];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path=C:/Users/Brandon/Documents/NetBeansProjects/Loader/build/classes";
options[2].optionString = "-verbose:class";
jvm_args.version = JNI_VERSION_1_6;
jvm_args.nOptions = 3;
jvm_args.options = options;
jvm_args.ignoreUnrecognized = false;
//JNI_GetDefaultJavaVMInitArgs(&jvm_args);
JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &jvm_args);
jclass MainClass = env->FindClass("loader.Main");
//Crashes on the next line:
jmethodID MainMethod = env->GetStaticMethodID(MainClass, "main", "([Ljava/lang/String;)V");
MessageBox(NULL, "", "", 0);
Sleep(1000);
jvm->DestroyJavaVM();
delete[] options;
}
My java code looks like:
package loader;
public class Main {
public static void main(String[] args) {
//JavaProcess.exec(ClientApplet.class);
System.out.println("Hello!");
}
}
And the verbose prints:
[Loaded loader.Main from file:/C:/Users/Brandon/Documents/NetBeansProjects/Loader/build/classes/]
Process returned -1073741571 (0xC00000FD) execution time : 1.730 s
Press any key to continue.
What am I doing wrong? Why does it fail to call the method?
The JNI.dll that I loaded is from: C:\Program Files\Java\jdk1.7.0_21\jre\bin\server\jvm.dll because the latest Java 7u25 doesn't have a bin\client\jvm.dll.
I even statically linked to the jvm.lib: C:\Program Files\Java\jdk1.7.0_21\lib\jvm.lib.
jclass MainClass = env->FindClass("loader.Main");
This is wrong. You have to use slashes instead of dots when using JNI functions, just like in method signatures.
The correct code is:
jclass MainClass = env->FindClass("loader/Main");

How to create .dylib from existing c project (concorde) for JNI

I am trying to use concorde in a java app
but I can't figure it out.
I have created the java class as follows:
package jconcorde;
public class TSP {
static {
System.loadLibrary("tsp");
}
private native int[] getNNTour(String path);
public static void main(String[] args) {
int [] a = new TSP().getNNTour("st70.tsp");
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
after compiling it using javac -h
I got the following file: jconcorde_TSP.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jconcorde_TSP */
#ifndef _Included_jconcorde_TSP
#define _Included_jconcorde_TSP
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jconcorde_TSP
* Method: getNNTour
* Signature: (Ljava/lang/String;)[I
*/
JNIEXPORT jintArray JNICALL Java_jconcorde_TSP_getNNTour
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
inside of concorde there is a folder named KDTREE i have copied from the kd_main.c some of it into my jconcorde_TSP.c as follows:
#include <jni.h> // JNI header provided by JDK
#include <stdio.h> // C Standard IO Header
#include "jconcorde_TSP.h" // Generated
#include "machdefs.h"
#include "util.h"
#include "kdtree.h"
#include <string.h>
static int norm = CC_EUCLIDEAN;
static int seed = 0;
static char *nodefile2 = (char *) NULL;
JNIEXPORT jintArray JNICALL Java_jconcorde_TSP_getNNTour(JNIEnv *env, jobject thisObj, jstring jstr) {
const char *nodefile = (*env)->GetStringUTFChars(env, jstr, NULL);
strcpy(nodefile2, nodefile);
double val, szeit;
CCdatagroup dat;
int ncount;
int *ttour = (int *) NULL, *tour2 = (int *) NULL;
CCrandstate rstate;
CCutil_init_datagroup (&dat);
seed = (int) CCutil_real_zeit ();
CCutil_sprand (seed, &rstate);
CCutil_gettsplib (nodefile2, &ncount, &dat);
CCutil_dat_getnorm (&dat, &norm);
ttour = CC_SAFE_MALLOC (ncount, int);
szeit = CCutil_zeit ();
if (CCkdtree_nearest_neighbor_tour ((CCkdtree *) NULL, ncount,
CCutil_lprand (&rstate) % ncount, &dat, ttour, &val, &rstate)) {
fprintf (stderr, "Nearest neighbor failed\n");
}
jintArray outJNIArray = (*env)->NewIntArray(env, ncount);
(*env)->SetIntArrayRegion(env, outJNIArray, 0 , ncount, ttour);
return outJNIArray;
}
and the original Makefile of the KDTREE is as follows:
# Generated automatically from Makefile.in by configure.
#
# This file is part of CONCORDE
#
# (c) Copyright 1995--1999 by David Applegate, Robert Bixby,
# Vasek Chvatal, and William Cook
#
# Permission is granted for academic research use. For other uses,
# contact the authors for licensing options.
#
# Use at your own risk. We make no guarantees about the
# correctness or usefulness of this code.
#
SHELL = /bin/sh
SRCROOT = ..
BLDROOT = ..
CCINCDIR=$(SRCROOT)/INCLUDE
srcdir = .
CC = gcc
CFLAGS = -g -O3 -arch x86_64 -I$(BLDROOT)/INCLUDE -I$(CCINCDIR)
LDFLAGS = -g -O3 -arch x86_64
LIBFLAGS = -lm
RANLIB = ranlib
OBJ_SUFFIX = o
o = $(OBJ_SUFFIX)
THISLIB=kdtree.a
LIBSRCS=kdbuild.c kdnear.c kdspan.c kdtwoopt.c
ALLSRCS=kd_main.c $(LIBSRCS)
LIBS=$(BLDROOT)/UTIL/util.a
all: kdtree $(THISLIB)
everything: all kdtree
kdtree: kd_main.$o $(THISLIB) $(LIBS)
$(CC) $(LDFLAGS) -o $# kd_main.$o $(THISLIB) $(LIBS) $(LIBFLAGS)
clean:
-rm -f *.$o $(THISLIB) kdtree
OBJS=$(LIBSRCS:.c=.o)
$(THISLIB): $(OBJS)
$(AR) $(ARFLAGS) $(THISLIB) $(OBJS)
$(RANLIB) $(THISLIB)
.PHONY: $(BLDROOT)/concorde.a
$(BLDROOT)/concorde.a: $(OBJS)
$(AR) $(ARFLAGS) $(BLDROOT)/concorde.a $(OBJS)
$(RANLIB) $(BLDROOT)/concorde.a
include ../INCLUDE/Makefile.common
# DO NOT DELETE THIS LINE -- make depend depends on it.
I=$(CCINCDIR)
I2=$(BLDROOT)/INCLUDE
kd_main.$o: kd_main.c $(I)/machdefs.h $(I2)/config.h $(I)/util.h \
$(I)/kdtree.h
kdbuild.$o: kdbuild.c $(I)/machdefs.h $(I2)/config.h $(I)/util.h \
$(I)/kdtree.h $(I)/macrorus.h
kdnear.$o: kdnear.c $(I)/machdefs.h $(I2)/config.h $(I)/kdtree.h \
$(I)/util.h $(I)/macrorus.h
kdspan.$o: kdspan.c $(I)/machdefs.h $(I2)/config.h $(I)/kdtree.h \
$(I)/util.h $(I)/macrorus.h
kdtwoopt.$o: kdtwoopt.c $(I)/machdefs.h $(I2)/config.h $(I)/util.h \
$(I)/kdtree.h $(I)/macrorus.h
I have copied both of jconcorde_TSP.c and jconcorde_TSP.h into the KDTREE folder
what do I need to do in order to create the libtsp.dylib for the java code?
I have tried this:
gcc -g -O3 -arch x86_64 -I../INCLUDE -I../INCLUDE -I/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home//include -I/Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home//include/darwin -c -dynamiclib -o libtsp.dylib jconcorde_TSP.c ../UTIL/util.a -lm
but after I copied the libtsp.dylib into the java project I get this exception:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/home_pc/NetBeansProjects/JConcorde/libtsp.dylib: dlopen(/Users/home_pc/NetBeansProjects/JConcorde/libtsp.dylib, 1): no suitable image found. Did find:
/Users/home_pc/NetBeansProjects/JConcorde/libtsp.dylib: mach-o, but wrong filetype
/Users/home_pc/NetBeansProjects/JConcorde/libtsp.dylib: mach-o, but wrong filetype
at java.base/java.lang.ClassLoader$NativeLibrary.load0(Native Method)
at java.base/java.lang.ClassLoader$NativeLibrary.load(ClassLoader.java:2430)
at java.base/java.lang.ClassLoader$NativeLibrary.loadLibrary(ClassLoader.java:2487)
at java.base/java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2684)
at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2649)
at java.base/java.lang.Runtime.loadLibrary0(Runtime.java:829)
at java.base/java.lang.System.loadLibrary(System.java:1867)
at jconcorde.TSP.<clinit>(TSP.java:15)
/Users/home_pc/NetBeansProjects/JConcorde/nbproject/build-impl.xml:1328: The following error occurred while executing this line:
/Users/home_pc/NetBeansProjects/JConcorde/nbproject/build-impl.xml:948: Java returned: 1
what am I doing wrong?
After a discussion in the comments with #P.N.N the solution was found.
The correct compilation command is:
gcc -g -O3 -arch x86_64 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -L"../UTIL" -I"../INCLUDE" -I"../" -dynamiclib -o libtsp.dylib jconcorde_TSP.c ../UTIL/util.a kdtree.a
Compared to the original command the solution was to add a library path adding -L"../UTIL" to the compilation and then add a missing static library to the command kdtree.a

JNI - WMI connection error

I have a java Web application to collect some data from local and remote windows machine. I am using wmi connection to connect to machine.
I use tomcat as Web server. For wmi connection i wrote c++ code and connect java and c++ using JNI. When i start the server and enter login details, tomcat crashes.
In log file error is..
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffd1e6e2931, pid=3940, tid=0x0000000000000a6c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [Verify_.dll+0x2931]
#
I am using tomcat 8.5.28 and jdk1.8.0_162
Here is my java code: Verify_.java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class Verify_ extends HttpServlet{
public native int connect();
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.loadLibrary("Verify_");
Verify_ verify = new Verify_();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String ServerName = request.getParameter("servername");
String UserName = request.getParameter("username");
String Password = request.getParameter("password");
int status = verify.connect();
if(status == 0)
out.println("Connected to " + ServerName);
else if(status == 1)
out.println("failed to initialize CoInitializeEx");
else if(status == 2)
out.println("failed to initialize CoInitializeSecurity");
else if(status == 3)
out.println("failed to initialize CoCreateInstance");
else if(status == 4)
out.println("failed to connect to Server");
else
out.println(status);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
doGet(request,response);
}}
Here is JNI interface code: Verify_.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Verify_ */
#ifndef _Included_Verify_
#define _Included_Verify_
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Verify_
* Method: connect
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_Verify_1_connect
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Here is C++ code: Verify_.cpp
#include <iostream>
#include <wbemidl.h>
#include <conio.h>
#include <windows.h>
#include <comdef.h>
#include <wincred.h>
#include <string.h>
#include "Verify_.h"
#pragma comment(lib, "credui.lib")
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "Ole32.lib")
#define _WIN32_DCOM
JNIEXPORT jint JNICALL Java_Verify_1_connect (JNIEnv *, jobject){
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2"));
wcscpy(pszUserName, BSTR(L"Administrator"));
wcscpy(pszPassword, BSTR(L"qwerty1233"));
HRESULT hr;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) {
return 1;
}
hr = CoInitializeSecurity(
NULL, // Security descriptor
-1, // COM negotiates authentication service
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation level for proxies
NULL, // Authentication info
EOAC_NONE, // Additional capabilities of the client or server
NULL); // Reserved
if (FAILED(hr)) {
CoUninitialize();
return 2;
}
IWbemLocator *pLoc = 0;
hr = CoCreateInstance(CLSID_WbemLocator, 0,
CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
if (FAILED(hr)){
CoUninitialize();
return 3;
}
IWbemServices *pSvc = NULL;
// Connect to the root\default namespace with the current user.
hr = pLoc->ConnectServer(
pszRoot, //namespace
pszUserName, // User name
pszPassword, // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc); // IWbemServices proxy
if (FAILED(hr)){
pLoc->Release();
CoUninitialize();
return 4;
}
// pSvc->Release();
// pLoc->Release();
CoUninitialize();
return 0;
}
i am trying for past 5 days. Pls help me. If there is any other way tell me..
Thanks in advance
0xc0000005
-> Access violation, mostly because using a NULL pointer.
BSTR pszRoot,pszUserName,pszPassword;
wcscpy(pszRoot, BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2"));
You have to allocate memory when using wcscpy. So, the wcscopy is called with an invalid (random) address (in Debugmode: With NULL).
I'm not sure you are handling BSTR correct (I did not know BSTR). See definition of BSTR:
typedef OLECHAR *BSTR;
Why not assign directly?
pszRoot = BSTR(L"\\\\172.21.111.250\\ROOT\\cimv2");
thanks Ralph Erdt
i changed this part
BSTR pszRoot,pszUserName,pszPassword;
pszRoot = ::SysAllocString(L"\\\\172.21.111.250\\ROOT\\cimv2");
pszUserName = ::SysAllocString(L"Administrator");
pszPassword = ::SysAllocString(L"qwerty1233");

Calling main method from JNI fails

I created a C++ class that is supposed to call Main.main by following: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/invocation.html#wp9502.
I didn't get it to work so I followed: http://www.coderanch.com/t/525082/CPP/create-JVM-native-code-call
and :
imp_JNI_Crea">http://www.codeproject.com/Questions/263687/Linker-error-undefined-reference-to-imp_JNI_Crea
None of which worked. So I changed my code back to what the Invocation API article by oracle says (the first link).
My C++ code looks like:
In JNI.hpp file:
#include <jni.h>
#include <windows.h>
#include <iostream>
class Jvm
{
private:
JavaVM* jvm;
JNIEnv* env;
JavaVMInitArgs jvm_args;
JavaVMOption* options;
public:
Jvm();
};
In JNI.cpp file:
Jvm::Jvm()
{
options = new JavaVMOption[3];
options[0].optionString = "-Djava.compiler=NONE";
options[1].optionString = "-Djava.class.path=C:/Users/Brandon/Documents/NetBeansProjects/Loader/build/classes";
options[2].optionString = "-verbose:class";
jvm_args.version = JNI_VERSION_1_6;
jvm_args.nOptions = 3;
jvm_args.options = options;
jvm_args.ignoreUnrecognized = false;
//JNI_GetDefaultJavaVMInitArgs(&jvm_args);
JNI_CreateJavaVM(&jvm, reinterpret_cast<void**>(&env), &jvm_args);
jclass MainClass = env->FindClass("loader.Main");
//Crashes on the next line:
jmethodID MainMethod = env->GetStaticMethodID(MainClass, "main", "([Ljava/lang/String;)V");
MessageBox(NULL, "", "", 0);
Sleep(1000);
jvm->DestroyJavaVM();
delete[] options;
}
My java code looks like:
package loader;
public class Main {
public static void main(String[] args) {
//JavaProcess.exec(ClientApplet.class);
System.out.println("Hello!");
}
}
And the verbose prints:
[Loaded loader.Main from file:/C:/Users/Brandon/Documents/NetBeansProjects/Loader/build/classes/]
Process returned -1073741571 (0xC00000FD) execution time : 1.730 s
Press any key to continue.
What am I doing wrong? Why does it fail to call the method?
The JNI.dll that I loaded is from: C:\Program Files\Java\jdk1.7.0_21\jre\bin\server\jvm.dll because the latest Java 7u25 doesn't have a bin\client\jvm.dll.
I even statically linked to the jvm.lib: C:\Program Files\Java\jdk1.7.0_21\lib\jvm.lib.
jclass MainClass = env->FindClass("loader.Main");
This is wrong. You have to use slashes instead of dots when using JNI functions, just like in method signatures.
The correct code is:
jclass MainClass = env->FindClass("loader/Main");

Categories

Resources