📄 jk_jni_worker.c
字号:
if (jk_get_worker_str_prop(props, p->name, "java2opts", &str_config)) {
/* jk_log(l, JK_LOG_DEBUG, "Got opts: %s", str_config); */
p->java2opts = jk_parse_sysprops(&p->p, str_config);
}
if (jk_get_worker_int_prop(props, p->name, "java2lax", &mem_config)) {
p->java2lax = mem_config ? JK_TRUE : JK_FALSE;
}
#endif
if (jk_get_worker_libpath(props, p->name, &str_config)) {
jk_append_libpath(&p->p, str_config);
}
if (!load_jvm_dll(p, l)) {
jk_log(l, JK_LOG_EMERG, "can't load jvm dll");
/* [V] no detach needed here */
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (!open_jvm(p, &env, l)) {
jk_log(l, JK_LOG_EMERG, "can't open jvm");
/* [V] no detach needed here */
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (!get_bridge_object(p, env, l)) {
jk_log(l, JK_LOG_EMERG, "can't get bridge object");
/* [V] the detach here may segfault on 1.1 JVM... */
detach_from_jvm(p, l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (!get_method_ids(p, env, l)) {
jk_log(l, JK_LOG_EMERG, "can't get method ids");
/* [V] the detach here may segfault on 1.1 JVM... */
detach_from_jvm(p, l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
p->was_verified = JK_TRUE;
p->tmp_env = env;
JK_TRACE_EXIT(l);
return JK_TRUE;
}
static int JK_METHOD init(jk_worker_t *pThis,
jk_map_t *props,
jk_worker_env_t *we, jk_logger_t *l)
{
jni_worker_t *p;
JNIEnv *env;
JK_TRACE_ENTER(l);
if (!pThis || !pThis->worker_private) {
JK_LOG_NULL_PARAMS(l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
p = pThis->worker_private;
if (p->was_initialized) {
jk_log(l, JK_LOG_DEBUG, "done (been here!)");
JK_TRACE_EXIT(l);
return JK_TRUE;
}
if (!p->jvm ||
!p->jk_java_bridge_object ||
!p->jk_service_method ||
!p->jk_startup_method || !p->jk_shutdown_method) {
jk_log(l, JK_LOG_EMERG, "worker not set completely");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
/* [V] init is called from the same thread that called validate */
/* there is no need to attach to the JVM, just get the env */
/* if(env = attach_to_jvm(p,l)) { */
if ((env = p->tmp_env)) {
jstring cmd_line = (jstring) NULL;
jstring stdout_name = (jstring) NULL;
jstring stderr_name = (jstring) NULL;
jint rc = 0;
/* AS400/BS2000 need EBCDIC to ASCII conversion for JNI */
if (p->tomcat_cmd_line) {
cmd_line =
(*env)->NewStringUTF(env,
strdup_ascii(&p->p, p->tomcat_cmd_line));
}
if (p->stdout_name) {
stdout_name =
(*env)->NewStringUTF(env,
strdup_ascii(&p->p, p->stdout_name));
}
if (p->stderr_name) {
stderr_name =
(*env)->NewStringUTF(env,
strdup_ascii(&p->p, p->stderr_name));
}
jk_log(l, JK_LOG_DEBUG,
"calling Tomcat to intialize itself...");
rc = (*env)->CallIntMethod(env, p->jk_java_bridge_object,
p->jk_startup_method, cmd_line,
stdout_name, stderr_name);
detach_from_jvm(p, l);
if (rc) {
p->was_initialized = JK_TRUE;
jk_log(l, JK_LOG_DEBUG, "Tomcat initialized OK, done");
JK_TRACE_EXIT(l);
return JK_TRUE;
}
else {
jk_log(l, JK_LOG_EMERG, "could not initialize Tomcat");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
}
else {
jk_log(l, JK_LOG_ERROR,
"In init, FIXME: init didn't gen env from validate!");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
}
static int JK_METHOD get_endpoint(jk_worker_t *pThis,
jk_endpoint_t **pend, jk_logger_t *l)
{
/* [V] This slow, needs replacement */
jni_endpoint_t *p;
JK_TRACE_ENTER(l);
if (!pThis || !pThis->worker_private || !pend) {
JK_LOG_NULL_PARAMS(l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
p = (jni_endpoint_t *) calloc(1, sizeof(jni_endpoint_t));
if (p) {
p->attached = JK_FALSE;
p->env = NULL;
p->worker = pThis->worker_private;
p->endpoint.endpoint_private = p;
p->endpoint.service = service;
p->endpoint.done = done;
*pend = &p->endpoint;
JK_TRACE_EXIT(l);
return JK_TRUE;
}
else {
jk_log(l, JK_LOG_ERROR,
"could not allocate endpoint");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
}
static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l)
{
jni_worker_t *p;
JNIEnv *env;
JK_TRACE_ENTER(l);
if (!pThis || !*pThis || !(*pThis)->worker_private) {
JK_LOG_NULL_PARAMS(l);
JK_TRACE_EXIT(l);
return JK_FALSE;
}
p = (*pThis)->worker_private;
if (!p->jvm) {
jk_log(l, JK_LOG_DEBUG, "JVM not intantiated");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if (!p->jk_java_bridge_object || !p->jk_shutdown_method) {
jk_log(l, JK_LOG_DEBUG, "Tomcat not intantiated");
JK_TRACE_EXIT(l);
return JK_FALSE;
}
if ((env = attach_to_jvm(p, l))) {
jk_log(l, JK_LOG_DEBUG, "shutting down Tomcat...");
(*env)->CallVoidMethod(env,
p->jk_java_bridge_object,
p->jk_shutdown_method);
detach_from_jvm(p, l);
}
jk_close_pool(&p->p);
free(p);
jk_log(l, JK_LOG_DEBUG, "destroyed");
JK_TRACE_EXIT(l);
return JK_TRUE;
}
int JK_METHOD jni_worker_factory(jk_worker_t **w,
const char *name, jk_logger_t *l)
{
jni_worker_t *private_data;
JK_TRACE_ENTER(l);
if (!name || !w) {
JK_LOG_NULL_PARAMS(l);
JK_TRACE_EXIT(l);
return 0;
}
if (the_singleton_jni_worker) {
jk_log(l, JK_LOG_DEBUG,
"instance already created");
*w = the_singleton_jni_worker;
JK_TRACE_EXIT(l);
return JK_JNI_WORKER_TYPE;
}
private_data = (jni_worker_t *) malloc(sizeof(jni_worker_t));
if (!private_data) {
jk_log(l, JK_LOG_ERROR,
"memory allocation error");
JK_TRACE_EXIT(l);
return 0;
}
jk_open_pool(&private_data->p,
private_data->buf, sizeof(jk_pool_atom_t) * TINY_POOL_SIZE);
private_data->name = jk_pool_strdup(&private_data->p, name);
if (!private_data->name) {
jk_log(l, JK_LOG_ERROR,
"memory allocation error");
jk_close_pool(&private_data->p);
free(private_data);
JK_TRACE_EXIT(l);
return 0;
}
private_data->was_verified = JK_FALSE;
private_data->was_initialized = JK_FALSE;
private_data->jvm = NULL;
private_data->tmp_env = NULL;
private_data->jk_java_bridge_object = (jobject) NULL;
private_data->jk_java_bridge_class = (jclass) NULL;
private_data->jk_startup_method = (jmethodID) NULL;
private_data->jk_service_method = (jmethodID) NULL;
private_data->jk_shutdown_method = (jmethodID) NULL;
private_data->tomcat_cmd_line = NULL;
private_data->tomcat_classpath = NULL;
private_data->bridge_type = TC33_BRIDGE_TYPE;
private_data->jvm_dll_path = NULL;
private_data->tomcat_ms = 0;
private_data->tomcat_mx = 0;
private_data->sysprops = NULL;
#ifdef JNI_VERSION_1_2
private_data->java2opts = NULL;
private_data->java2lax = JK_TRUE;
#endif
private_data->stdout_name = NULL;
private_data->stderr_name = NULL;
private_data->worker.worker_private = private_data;
private_data->worker.validate = validate;
private_data->worker.init = init;
private_data->worker.get_endpoint = get_endpoint;
private_data->worker.destroy = destroy;
private_data->worker.retries = JK_RETRIES;
*w = &private_data->worker;
the_singleton_jni_worker = &private_data->worker;
JK_TRACE_EXIT(l);
return JK_JNI_WORKER_TYPE;
}
static int load_jvm_dll(jni_worker_t * p, jk_logger_t *l)
{
#ifdef WIN32
HINSTANCE hInst = LoadLibrary(p->jvm_dll_path);
if (hInst) {
(FARPROC) jni_create_java_vm =
GetProcAddress(hInst, "JNI_CreateJavaVM");
(FARPROC) jni_get_created_java_vms =
GetProcAddress(hInst, "JNI_GetCreatedJavaVMs");
(FARPROC) jni_get_default_java_vm_init_args =
GetProcAddress(hInst, "JNI_GetDefaultJavaVMInitArgs");
jk_log(l, JK_LOG_DEBUG, "Loaded all JNI procs");
if (jni_create_java_vm && jni_get_default_java_vm_init_args
&& jni_get_created_java_vms) {
return JK_TRUE;
}
FreeLibrary(hInst);
}
#elif defined(NETWARE) && !defined(__NOVELL_LIBC__)
int javaNlmHandle = FindNLMHandle("JVM");
if (0 == javaNlmHandle) {
/* if we didn't get a handle, try to load java and retry getting the */
/* handle */
spawnlp(P_NOWAIT, "JVM.NLM", NULL);
ThreadSwitchWithDelay();
javaNlmHandle = FindNLMHandle("JVM");
if (0 == javaNlmHandle)
printf("Error loading Java.");
}
if (0 != javaNlmHandle) {
jni_create_java_vm = ImportSymbol(GetNLMHandle(), "JNI_CreateJavaVM");
jni_get_created_java_vms =
ImportSymbol(GetNLMHandle(), "JNI_GetCreatedJavaVMs");
jni_get_default_java_vm_init_args =
ImportSymbol(GetNLMHandle(), "JNI_GetDefaultJavaVMInitArgs");
}
if (jni_create_java_vm && jni_get_default_java_vm_init_args
&& jni_get_created_java_vms) {
return JK_TRUE;
}
#elif defined(AS400)
jk_log(l, JK_LOG_DEBUG,
"Direct reference to JNI entry points (no SRVPGM)");
jni_create_java_vm = &JNI_CreateJavaVM;
jni_get_default_java_vm_init_args = &JNI_GetDefaultJavaVMInitArgs;
jni_get_created_java_vms = &JNI_GetCreatedJavaVMs;
#else
void *handle;
jk_log(l, JK_LOG_DEBUG, "loading JVM %s", p->jvm_dll_path);
handle = dlopen(p->jvm_dll_path, RTLD_NOW | RTLD_GLOBAL);
if (!handle) {
jk_log(l, JK_LOG_EMERG,
"Can't load native library %s : %s", p->jvm_dll_path,
dlerror());
}
else {
jni_create_java_vm = dlsym(handle, "JNI_CreateJavaVM");
jni_get_default_java_vm_init_args =
dlsym(handle, "JNI_GetDefaultJavaVMInitArgs");
jni_get_created_java_vms = dlsym(handle, "JNI_GetCreatedJavaVMs");
if (jni_create_java_vm && jni_get_default_java_vm_init_args &&
jni_get_created_java_vms) {
jk_log(l, JK_LOG_DEBUG,
"In load_jvm_dll, symbols resolved, done");
return JK_TRUE;
}
jk_log(l, JK_LOG_EMERG,
"Can't resolve JNI_CreateJavaVM or JNI_GetDefaultJavaVMInitArgs");
dlclose(handle);
}
#endif
return JK_FALSE;
}
static int open_jvm(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l)
{
#ifdef JNI_VERSION_1_2
int jvm_version = detect_jvm_version(l);
switch (jvm_version) {
case JNI_VERSION_1_1:
return open_jvm1(p, env, l);
case JNI_VERSION_1_2:
return open_jvm2(p, env, l);
default:
return JK_FALSE;
}
#else
/* [V] Make sure this is _really_ visible */
#warning -------------------------------------------------------
#warning NO JAVA 2 HEADERS! SUPPORT FOR JAVA 2 FEATURES DISABLED
#warning -------------------------------------------------------
return open_jvm1(p, env, l);
#endif
}
static int open_jvm1(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l)
{
JDK1_1InitArgs vm_args;
JNIEnv *penv;
int err;
*env = NULL;
JK_TRACE_ENTER(l);
vm_args.version = JNI_VERSION_1_1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -