#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <cx/map.h>
#include "jvm.h"
#include "daemon/request.h"
#ifdef __i386
#define LIBJVM "/usr/java/jre/lib/i386/server/libjvm.so"
#else
#endif
static JNIEnv *env =
NULL;
static JavaVM *jvm =
NULL;
static jobject plugin_instance =
NULL;
static jmethodID load_jmodules_method =
NULL;
static jmethodID exec_method =
NULL;
int jvm_init(pblock *pb, Session *sn, Request *rq) {
void *lib = dlopen(
LIBJVM,
RTLD_GLOBAL |
RTLD_NOW);
if(!lib) {
log_ereport(
LOG_FAILURE,
"Cannot load libjvm.so");
return REQ_ABORTED;
}
void *sym = dlsym(lib,
"JNI_CreateJavaVM");
if(sym ==
NULL) {
log_ereport(
LOG_FAILURE,
"Cannot get symbol JNI_CreateJavaVM from lib");
return REQ_ABORTED;
}
JavaVMInitArgs vm_args;
JavaVMOption options[
2];
options[
0].optionString =
"-Djava.class.path=lib/wsrt.jar";
options[
1].optionString =
"-Djava.library.path=lib/";
vm_args.version =
JNI_VERSION_1_6;
vm_args.options = options;
vm_args.nOptions =
2;
vm_args.ignoreUnrecognized =
JNI_TRUE;
CreateJVMFunc create_jvm = (CreateJVMFunc)sym;
if(create_jvm(&jvm, (
void**)&env, &vm_args)) {
dlclose(lib);
log_ereport(
LOG_FAILURE,
"Cannot create JVM");
}
jclass cls = (*env)->FindClass(env,
"webserver/ServerPlugin");
if(!cls) {
log_ereport(
LOG_FAILURE,
"jvm-init: missing or broken wsrt.jar");
log_ereport(
LOG_FAILURE,
"jvm-init: missing class webserver.ServerPlugin");
return REQ_ABORTED;
}
jmethodID constr = (*env)->GetMethodID(env, cls,
"<init>",
"()V");
if(!constr) {
log_ereport(
LOG_FAILURE,
"jvm-init: missing or broken wsrt.jar");
log_ereport(
LOG_FAILURE,
"jvm-init: missing constructor");
return REQ_ABORTED;
}
plugin_instance = (*env)->NewObject(env, cls, constr);
if(!plugin_instance) {
log_ereport(
LOG_FAILURE,
"jvm-init: cannot create ServerPlugin instance");
return REQ_ABORTED;
}
load_jmodules_method = (*env)->GetMethodID(
env,
cls,
"loadModule",
"(Ljava/lang/String;Ljava/lang/String;)I");
if(!load_jmodules_method) {
log_ereport(
LOG_FAILURE,
"jvm-init: missing or broken wsrt.jar");
log_ereport(
LOG_FAILURE,
"jvm-init: missing method (loadModule)");
return REQ_ABORTED;
}
exec_method = (*env)->GetMethodID(
env,
cls,
"exec",
"(I)I");
if(!exec_method) {
log_ereport(
LOG_FAILURE,
"jvm-init: missing or broken wsrt.jar");
log_ereport(
LOG_FAILURE,
"jvm-init: missing method (exec)");
return REQ_ABORTED;
}
return REQ_PROCEED;
}
int load_jmodules(pblock *pb, Session *sn, Request *rq) {
char *jar = pblock_findval(
"jar", pb);
char *classes = pblock_findval(
"classes", pb);
if(!jar || !classes) {
log_ereport(
LOG_MISCONFIG,
"load-jmodule: missing parameters (jar, classes)");
return REQ_ABORTED;
}
if(!plugin_instance) {
log_ereport(
LOG_FAILURE,
"load-jmodules: java plugin not properly loaded");
return REQ_ABORTED;
}
if(!load_jmodules_method) {
log_ereport(
LOG_FAILURE,
"load-jmodules: java plugin not properly loaded");
return REQ_ABORTED;
}
jstring jar_param = (*env)->NewStringUTF(env, jar);
jstring classes_param = (*env)->NewStringUTF(env, classes);
jint ret = (*env)->CallIntMethod(
env,
plugin_instance,
load_jmodules_method,
jar_param,
classes_param);
(*env)->DeleteLocalRef(env, jar_param);
(*env)->DeleteLocalRef(env, classes_param);
return ret;
}
int jexec(pblock *pb, Session *sn, Request *rq) {
return REQ_NOACTION;
}
int jvm_method_exec(FuncStruct *func, pblock *pb, Session *sn, Request *rq) {
printf(
"jvm_method_exec: %d\n", func);
NSAPIRequest *nrq = (NSAPIRequest*)rq;
JNIEnv *e =
NULL;
int r = (*jvm)->AttachCurrentThread(jvm, (
void**)&e,
NULL);
jint index = (jint)func->exec_data;
printf(
"(C) exec: %d\n", index);
jint ret = (*env)->CallIntMethod(
env,
plugin_instance,
exec_method,
index);
return ret;
}