📄 jk_jni_worker.c
字号:
if (0 != jni_get_default_java_vm_init_args(&vm_args)) { jk_log(l, JK_LOG_EMERG, "can't get default vm init args"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "got default jvm args"); if (vm_args.classpath) { unsigned len = strlen(vm_args.classpath) + strlen(p->tomcat_classpath) + 3; char *tmp = jk_pool_alloc(&p->p, len); if (tmp) { sprintf(tmp, "%s%c%s", strdup_ascii(&p->p, p->tomcat_classpath), PATH_SEPERATOR, vm_args.classpath); p->tomcat_classpath = tmp; } else { jk_log(l, JK_LOG_EMERG, "allocation error for classpath"); JK_TRACE_EXIT(l); return JK_FALSE; } } vm_args.classpath = p->tomcat_classpath; if (p->tomcat_mx) { vm_args.maxHeapSize = p->tomcat_mx; } if (p->tomcat_ms) { vm_args.minHeapSize = p->tomcat_ms; } if (p->sysprops) { /* No EBCDIC to ASCII conversion here for AS/400 - later */ vm_args.properties = p->sysprops; } jk_log(l, JK_LOG_DEBUG, "In open_jvm1, about to create JVM..."); if ((err = jni_create_java_vm(&(p->jvm), &penv, &vm_args)) != 0) { jk_log(l, JK_LOG_EMERG, "could not create JVM, code: %d ", err); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "JVM created, done"); *env = penv; JK_TRACE_EXIT(l); return JK_TRUE;}#ifdef JNI_VERSION_1_2static int detect_jvm_version(jk_logger_t *l){ JNIEnv *env = NULL; JDK1_1InitArgs vm_args; JK_TRACE_ENTER(l); /* [V] Idea: ask for 1.2. If the JVM is 1.1 it will return 1.1 instead */ /* Note: asking for 1.1 won't work, 'cause 1.2 JVMs will return 1.1 */ vm_args.version = JNI_VERSION_1_2; if (0 != jni_get_default_java_vm_init_args(&vm_args)) { jk_log(l, JK_LOG_EMERG, "can't get default vm init args"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "found version: %X, done", vm_args.version); JK_TRACE_EXIT(l); return vm_args.version;}static char *build_opt_str(jk_pool_t *p, char *opt_name, char *opt_value, jk_logger_t *l){ unsigned len = strlen(opt_name) + strlen(opt_value) + 2; /* [V] IMHO, these should not be deallocated as long as the JVM runs */ char *tmp = jk_pool_alloc(p, len); if (tmp) { sprintf(tmp, "%s%s", opt_name, opt_value); return tmp; } else { jk_log(l, JK_LOG_EMERG, "allocation error for %s", opt_name); return NULL; }}static char *build_opt_int(jk_pool_t *p, char *opt_name, int opt_value, jk_logger_t *l){ /* [V] this should suffice even for 64-bit int */ unsigned len = strlen(opt_name) + 20 + 2; /* [V] IMHO, these should not be deallocated as long as the JVM runs */ char *tmp = jk_pool_alloc(p, len); if (tmp) { sprintf(tmp, "%s%d", opt_name, opt_value); return tmp; } else { jk_log(l, JK_LOG_EMERG, "allocation error for %s", opt_name); return NULL; }}static int open_jvm2(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l){ JavaVMInitArgs vm_args; JNIEnv *penv = NULL; JavaVMOption options[100]; int optn = 0, err; char *tmp; *env = NULL; JK_TRACE_ENTER(l); vm_args.version = JNI_VERSION_1_2; vm_args.options = options;/* AS/400 need EBCDIC to ASCII conversion to parameters passed to JNI *//* No conversion for ASCII based systems (what about BS2000 ?) */ if (p->tomcat_classpath) { jk_log(l, JK_LOG_DEBUG, "setting classpath to %s", p->tomcat_classpath); tmp = build_opt_str(&p->p, "-Djava.class.path=", p->tomcat_classpath, l); null_check(tmp); options[optn++].optionString = strdup_ascii(&p->p, tmp); } if (p->tomcat_mx) { jk_log(l, JK_LOG_DEBUG, "setting max heap to %d", p->tomcat_mx); tmp = build_opt_int(&p->p, "-Xmx", p->tomcat_mx, l); null_check(tmp); options[optn++].optionString = strdup_ascii(&p->p, tmp); } if (p->tomcat_ms) { jk_log(l, JK_LOG_DEBUG, "setting start heap to %d", p->tomcat_ms); tmp = build_opt_int(&p->p, "-Xms", p->tomcat_ms, l); null_check(tmp); options[optn++].optionString = strdup_ascii(&p->p, tmp); } if (p->sysprops) { int i = 0; while (p->sysprops[i]) { jk_log(l, JK_LOG_DEBUG, "setting %s", p->sysprops[i]); tmp = build_opt_str(&p->p, "-D", p->sysprops[i], l); null_check(tmp); options[optn++].optionString = strdup_ascii(&p->p, tmp); i++; } } if (p->java2opts) { int i = 0; while (p->java2opts[i]) { jk_log(l, JK_LOG_DEBUG, "using option: %s", p->java2opts[i]); /* Pass it "as is" */ options[optn++].optionString = strdup_ascii(&p->p, p->java2opts[i++]); } } vm_args.nOptions = optn; if (p->java2lax) { jk_log(l, JK_LOG_DEBUG, "the JVM will ignore unknown options"); vm_args.ignoreUnrecognized = JNI_TRUE; } else { jk_log(l, JK_LOG_DEBUG, "the JVM will FAIL if it finds unknown options"); vm_args.ignoreUnrecognized = JNI_FALSE; } jk_log(l, JK_LOG_DEBUG, "about to create JVM..."); err = jni_create_java_vm(&(p->jvm), &penv, &vm_args); if (JNI_EEXIST == err) {#ifdef AS400 long vmCount;#else int vmCount;#endif jk_log(l, JK_LOG_DEBUG, "JVM alread instantiated." "Trying to attach instead."); jni_get_created_java_vms(&(p->jvm), 1, &vmCount); if (NULL != p->jvm) penv = attach_to_jvm(p, l); if (NULL != penv) err = 0; } if (err != 0) { jk_log(l, JK_LOG_EMERG, "Fail-> could not create JVM, code: %d ", err); JK_TRACE_EXIT(l); return JK_FALSE; } *env = penv; jk_log(l, JK_LOG_DEBUG, "JVM created"); JK_TRACE_EXIT(l); return JK_TRUE;}#endifstatic int get_bridge_object(jni_worker_t * p, JNIEnv * env, jk_logger_t *l){ char *btype; char *ctype; jmethodID constructor_method_id; JK_TRACE_ENTER(l); switch (p->bridge_type) { case TC32_BRIDGE_TYPE: btype = TC32_JAVA_BRIDGE_CLASS_NAME; break; case TC33_BRIDGE_TYPE: btype = TC33_JAVA_BRIDGE_CLASS_NAME; break; case TC40_BRIDGE_TYPE: case TC41_BRIDGE_TYPE: case TC50_BRIDGE_TYPE: jk_log(l, JK_LOG_EMERG, "Bridge type %d not supported", p->bridge_type); JK_TRACE_EXIT(l); return JK_FALSE; }/* AS400/BS2000 need conversion from EBCDIC to ASCII before passing to JNI *//* for others, strdup_ascii is just jk_pool_strdup */ ctype = strdup_ascii(&p->p, btype); p->jk_java_bridge_class = (*env)->FindClass(env, ctype); if (!p->jk_java_bridge_class) { jk_log(l, JK_LOG_EMERG, "Can't find class %s", btype); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "In get_bridge_object, loaded %s bridge class", btype); constructor_method_id = (*env)->GetMethodID(env, p->jk_java_bridge_class, strdup_ascii(&p->p, "<init>"), /* method name */ strdup_ascii(&p->p, "()V")); /* method sign */ if (!constructor_method_id) { p->jk_java_bridge_class = (jclass) NULL; jk_log(l, JK_LOG_EMERG, "Can't find constructor"); JK_TRACE_EXIT(l); return JK_FALSE; } p->jk_java_bridge_object = (*env)->NewObject(env, p->jk_java_bridge_class, constructor_method_id); if (!p->jk_java_bridge_object) { p->jk_java_bridge_class = (jclass) NULL; jk_log(l, JK_LOG_EMERG, "Can't create new bridge object"); JK_TRACE_EXIT(l); return JK_FALSE; } p->jk_java_bridge_object = (jobject) (*env)->NewGlobalRef(env, p->jk_java_bridge_object); if (!p->jk_java_bridge_object) { jk_log(l, JK_LOG_EMERG, "Can't create global ref to bridge object"); p->jk_java_bridge_class = (jclass) NULL; p->jk_java_bridge_object = (jobject) NULL; JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE;}static int get_method_ids(jni_worker_t * p, JNIEnv * env, jk_logger_t *l){/* AS400/BS2000 need conversion from EBCDIC to ASCII before passing to JNI */ p->jk_startup_method = (*env)->GetMethodID(env, p->jk_java_bridge_class, strdup_ascii(&p->p, "startup"), strdup_ascii(&p->p, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I")); if (!p->jk_startup_method) { jk_log(l, JK_LOG_EMERG, "Can't find startup()"); return JK_FALSE; } p->jk_service_method = (*env)->GetMethodID(env, p->jk_java_bridge_class, strdup_ascii(&p->p, "service"), strdup_ascii(&p->p, "(JJ)I")); if (!p->jk_service_method) { jk_log(l, JK_LOG_EMERG, "Can't find service()"); return JK_FALSE; } p->jk_shutdown_method = (*env)->GetMethodID(env, p->jk_java_bridge_class, strdup_ascii(&p->p, "shutdown"), strdup_ascii(&p->p, "()V")); if (!p->jk_shutdown_method) { jk_log(l, JK_LOG_EMERG, "Can't find shutdown()"); return JK_FALSE; } return JK_TRUE;}static JNIEnv *attach_to_jvm(jni_worker_t * p, jk_logger_t *l){ JNIEnv *rc = NULL; /* [V] This message is important. If there are signal mask issues, * * the JVM usually hangs when a new thread tries to attach to it */ JK_TRACE_ENTER(l);#if defined LINUX && defined APACHE2_SIGHACK linux_signal_hack();#endif if (0 == (*(p->jvm))->AttachCurrentThread(p->jvm,#ifdef JNI_VERSION_1_2 (void **)#endif &rc, NULL)) { jk_log(l, JK_LOG_DEBUG, "In attach_to_jvm, attached ok"); JK_TRACE_EXIT(l); return rc; } jk_log(l, JK_LOG_ERROR, "In attach_to_jvm, cannot attach thread to JVM."); JK_TRACE_EXIT(l); return NULL;}/*static JNIEnv *attach_to_jvm(jni_worker_t *p){ JNIEnv *rc = NULL;#ifdef LINUX linux_signal_hack();#endif if(0 == (*(p->jvm))->AttachCurrentThread(p->jvm, #ifdef JNI_VERSION_1_2 (void **)#endif &rc, NULL)) { return rc; } return NULL;}*/static void detach_from_jvm(jni_worker_t * p, jk_logger_t *l){ JK_TRACE_ENTER(l); if (!p->jvm || !(*(p->jvm))) { jk_log(l, JK_LOG_ERROR, "cannot detach from NULL JVM."); } if (0 == (*(p->jvm))->DetachCurrentThread(p->jvm)) { jk_log(l, JK_LOG_DEBUG, "detached ok"); } else { jk_log(l, JK_LOG_ERROR, "cannot detach from JVM."); } JK_TRACE_EXIT(l);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -