Under one of my project I need to read VTextField GUI object of running oracle forms application, and set new value in it, I am able to inject my DLL into application and i am able to attach thorugh the current thread below is my code for this
JNIEnv* env;
JavaVM *jvm = NULL;
jsize jvm_count = 0;
jint res = 0;
#ifdef __STATIC_LIB_JVM
res = JNI_GetCreatedJavaVMs(&jvm, 1, &jvm_count);
#else
{
HINSTANCE hLibJVM;
typedef jint(JNICALL GetCreatedJavaVMs_t)(JavaVM**, jsize, jsize*);
GetCreatedJavaVMs_t *MyGetCreatedJavaVMs;
hLibJVM = LoadLibrary(L"jvm.dll");
MyGetCreatedJavaVMs = (GetCreatedJavaVMs_t*)GetProcAddress(hLibJVM, "JNI_GetCreatedJavaVMs");
res = MyGetCreatedJavaVMs(&jvm, 1, &jvm_count);
}
#endif
if (res == 0)
{
if (jvm_count == 0)
{
jvm = NULL;
}
}
else jvm = NULL;
bool mustDetach = false;
//jint retval = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
jint retval = jvm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (retval == JNI_EDETACHED)
{
JavaVMAttachArgs args;
args.version = JNI_VERSION_1_6;
args.name = NULL;
args.group = NULL;
retval = jvm->AttachCurrentThread((void**)&env, &args);
mustDetach = true; // to clean up afterwards
}
else{
fprintf(JNIStatus, "JNI is not processing\n"); // should never happen
}
if (retval != JNI_OK){
fprintf(JNIStatus, "JNI is not ok\n"); // should never happen
}
else{
fprintf(JNIStatus, "JNI is ok\n"); // should never happen
}
if (retval>=0)
fprintf(JNIStatus, "Attachcurrentthread was successfull\n");
here i am getting output as Attach current thread was successful, but after this when i am trying to find class using below code , system is not able to find class for this
char* strin;
strin = "abcdef";
jstring str = env->NewStringUTF(strin);
jfieldID fid;
jclass clazz = env->FindClass("oracle/forms/ui/VTextField");
if (clazz == NULL) {
fprintf(JNIStatus, "Can't find class %s", clazz);
}
Even i thought of that it because of local reference , but i tried to make jclass ob ject as global reference also but no luck :(
/* Create a global reference */
jclass clazzLUSCore = (_jclass*)env->NewGlobalRef(clazz);
/* The local reference is no longer useful */
env->DeleteLocalRef(clazz);
/* Is the global reference created successfully? */
if (clazzLUSCore == NULL) {
fprintf(JNIStatus, "Error - clazzLUSCore is still null when it is suppose to be global\n");
}
I am newbie in c++, please help me on this , i am not able to find running application class , I need to attain this without accessing server code.
As per @michael comment, i tried to add this but its throwing exception i think. so not able to get class name
JavaVM* gJvm = nullptr;
static jobject gClassLoader;
static jmethodID gFindClassMethod;
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *pjvm, void *reserved) {
gJvm = pjvm; // cache the JavaVM pointer
auto env = getEnv();
//replace with one of your classes in the line below
auto randomClass = env->FindClass("oracle/forms/ui/VTextField");
jclass classClass = env->GetObjectClass(randomClass);
auto classLoaderClass = env->FindClass("java/lang/ClassLoader");
auto getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader",
"()Ljava/lang/ClassLoader;");
gClassLoader = env->CallObjectMethod(randomClass, getClassLoaderMethod);
gFindClassMethod = env->GetMethodID(classLoaderClass, "findClass",
"(Ljava/lang/String;)Ljava/lang/Class;");
return JNI_VERSION_1_6;
}
jclass findClass(const char* name) {
return static_cast<jclass>(getEnv()->CallObjectMethod(gClassLoader, gFindClassMethod, getEnv()->NewStringUTF(name)));
}
JNIEnv* getEnv() {
JNIEnv *env;
int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (status < 0) {
status = gJvm->AttachCurrentThread((void**)&env, NULL);
if (status < 0) {
return nullptr;
}
}
return env;
}