diff options
Diffstat (limited to 'rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c')
-rw-r--r-- | rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c | 1267 |
1 files changed, 0 insertions, 1267 deletions
diff --git a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c deleted file mode 100644 index 048f4435..00000000 --- a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c +++ /dev/null @@ -1,1267 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*************************************************************************** - * Description: In process JNI worker * - * Author: Gal Shachor <shachor@il.ibm.com> * - * Based on: * - * Version: $Revision: 750428 $ * - ***************************************************************************/ - -#if !defined(WIN32) && !defined(NETWARE) && !defined(AS400) -#include <dlfcn.h> -#endif - -#include <jni.h> - -#include "jk_pool.h" -#include "jk_jni_worker.h" -#include "jk_util.h" - -#if !defined(JNI_VERSION_1_6) -#if defined LINUX && defined APACHE2_SIGHACK -#include <pthread.h> -#include <signal.h> -#include <bits/signum.h> -#endif - -#ifdef NETWARE -#ifdef __NOVELL_LIBC__ -#include <dlfcn.h> -#else -#include <nwthread.h> -#include <nwadv.h> -#endif -#endif - -#ifndef JNI_VERSION_1_1 -#define JNI_VERSION_1_1 0x00010001 -#endif - -/* probably on an older system that doesn't support RTLD_NOW or RTLD_LAZY. - * The below define is a lie since we are really doing RTLD_LAZY since the - * system doesn't support RTLD_NOW. - */ -#ifndef RTLD_NOW -#define RTLD_NOW 1 -#endif - -#ifndef RTLD_GLOBAL -#define RTLD_GLOBAL 0 -#endif - -#define null_check(e) if ((e) == 0) return JK_FALSE - -jint(JNICALL * jni_get_default_java_vm_init_args) (void *) = NULL; -jint(JNICALL * jni_create_java_vm) (JavaVM **, JNIEnv **, void *) = NULL; -#ifdef AS400 -jint(JNICALL * jni_get_created_java_vms) (JavaVM **, long, long *) = NULL; -#else -jint(JNICALL * jni_get_created_java_vms) (JavaVM **, int, int *) = NULL; -#endif - -#define TC33_JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/modules/server/JNIEndpoint") -#define TC32_JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/service/JNIEndpoint") - -static jk_worker_t *the_singleton_jni_worker = NULL; - -struct jni_worker -{ - - int was_verified; - int was_initialized; - - jk_pool_t p; - jk_pool_atom_t buf[TINY_POOL_SIZE]; - - /* - * JVM Object pointer. - */ - JavaVM *jvm; - - /* - * [V] JNIEnv used for boostraping from validate -> init w/o an attach - */ - JNIEnv *tmp_env; - - /* - * Web Server to Java bridge, instance and class. - */ - jobject jk_java_bridge_object; - jclass jk_java_bridge_class; - - /* - * Java methods ids, to jump into the JVM - */ - jmethodID jk_startup_method; - jmethodID jk_service_method; - jmethodID jk_shutdown_method; - - /* - * Command line for tomcat startup - */ - char *tomcat_cmd_line; - - /* - * Bridge Type, Tomcat 32/33/40/41/5 - */ - unsigned bridge_type; - - /* - * Classpath - */ - char *tomcat_classpath; - - /* - * Full path to the jni javai/jvm dll - */ - char *jvm_dll_path; - - /* - * Initial Java heap size - */ - unsigned tomcat_ms; - - /* - * Max Java heap size - */ - unsigned tomcat_mx; - - /* - * Java system properties - */ - char **sysprops; - -#ifdef JNI_VERSION_1_2 - /* - * Java 2 initialization options (-X... , -verbose etc.) - */ - char **java2opts; - - /* - * Java 2 lax/strict option checking (bool) - */ - int java2lax; -#endif - - /* - * stdout and stderr file names for Java - */ - char *stdout_name; - char *stderr_name; - - char *name; - jk_worker_t worker; -}; -typedef struct jni_worker jni_worker_t; - -struct jni_endpoint -{ - int attached; - JNIEnv *env; - jni_worker_t *worker; - - jk_endpoint_t endpoint; -}; -typedef struct jni_endpoint jni_endpoint_t; - - -static int load_jvm_dll(jni_worker_t * p, jk_logger_t *l); - -static int open_jvm(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l); - -static int open_jvm1(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l); - -#ifdef JNI_VERSION_1_2 -static int detect_jvm_version(jk_logger_t *l); - -static int open_jvm2(jni_worker_t * p, JNIEnv ** env, jk_logger_t *l); -#endif - - -static int get_bridge_object(jni_worker_t * p, JNIEnv * env, jk_logger_t *l); - -static int get_method_ids(jni_worker_t * p, JNIEnv * env, jk_logger_t *l); - -static JNIEnv *attach_to_jvm(jni_worker_t * p, jk_logger_t *l); - -static void detach_from_jvm(jni_worker_t * p, jk_logger_t *l); - - -/* - Duplicate string and convert it to ASCII on EBDIC based systems - Needed for at least AS/400 (before V5R4 ?) and BS2000 but what about other EBDIC systems ? -*/ -static void *strdup_ascii(jk_pool_t *p, char *s) -{ - char *rc; - rc = jk_pool_strdup(p, s); - -#if defined(AS400) || defined(_OSD_POSIX) - jk_xlate_to_ascii(rc, strlen(rc)); -#endif - - return rc; -} - -#if defined LINUX && defined APACHE2_SIGHACK -static void linux_signal_hack() -{ - sigset_t newM; - sigset_t old; - - sigemptyset(&newM); - pthread_sigmask(SIG_SETMASK, &newM, &old); - - sigdelset(&old, SIGUSR1); - sigdelset(&old, SIGUSR2); - sigdelset(&old, SIGUNUSED); - sigdelset(&old, SIGRTMIN); - sigdelset(&old, SIGRTMIN + 1); - sigdelset(&old, SIGRTMIN + 2); - pthread_sigmask(SIG_SETMASK, &old, NULL); -} - -static void print_signals(sigset_t * sset) -{ - int sig; - for (sig = 1; sig < 20; sig++) { - if (sigismember(sset, sig)) { - printf(" %d", sig); - } - } - printf("\n"); -} -#endif - -/* - * Return values of service() method for jni worker: - * return value is_error reason - * JK_FALSE JK_HTTP_SERVER_ERROR Invalid parameters (null values) - * Error during attach to the JNI backend - * Error during JNI call - * JK_TRUE JK_HTTP_OK All other cases - */ -static int JK_METHOD service(jk_endpoint_t *e, - jk_ws_service_t *s, - jk_logger_t *l, int *is_error) -{ - jni_endpoint_t *p; - jint rc; - - JK_TRACE_ENTER(l); - - if (!e || !e->endpoint_private || !s || !is_error) { - JK_LOG_NULL_PARAMS(l); - if (is_error) - *is_error = JK_HTTP_SERVER_ERROR; - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - p = e->endpoint_private; - - /* Set returned error to OK */ - *is_error = JK_HTTP_OK; - - if (!p->attached) { - /* Try to attach */ - if (!(p->env = attach_to_jvm(p->worker, l))) { - jk_log(l, JK_LOG_EMERG, "Attach failed"); - *is_error = JK_HTTP_SERVER_ERROR; - JK_TRACE_EXIT(l); - return JK_FALSE; - } - p->attached = JK_TRUE; - } - - /* we are attached now */ - - /* - * When we call the JVM we cannot know what happens - * So we can not recover !!! - */ - jk_log(l, JK_LOG_DEBUG, "In service, calling Tomcat..."); - - rc = (*(p->env))->CallIntMethod(p->env, - p->worker->jk_java_bridge_object, - p->worker->jk_service_method, - /* [V] For some reason gcc likes this pointer -> int -> jlong conversion, */ - /* but not the direct pointer -> jlong conversion. I hope it's okay. */ -#ifdef AS400 - s, l -#else - (jlong) (int)s, (jlong) (int)l -#endif - ); - - /* [V] Righ now JNIEndpoint::service() only returns 1 or 0 */ - if (rc) { - jk_log(l, JK_LOG_DEBUG, "Tomcat returned OK, done"); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - else { - jk_log(l, JK_LOG_ERROR, "Tomcat FAILED!"); - *is_error = JK_HTTP_SERVER_ERROR; - JK_TRACE_EXIT(l); - return JK_FALSE; - } -} - -static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l) -{ - jni_endpoint_t *p; - - JK_TRACE_ENTER(l); - if (!e || !*e || !(*e)->endpoint_private) { - JK_LOG_NULL_PARAMS(l); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - p = (*e)->endpoint_private; - - if (p->attached) { - detach_from_jvm(p->worker, l); - } - - free(p); - *e = NULL; - JK_TRACE_EXIT(l); - return JK_TRUE; -} - -static int JK_METHOD validate(jk_worker_t *pThis, - jk_map_t *props, - jk_worker_env_t *we, jk_logger_t *l) -{ - jni_worker_t *p; - int mem_config = 0; - int btype = 0; - const char *str_config = NULL; - 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_verified) { - jk_log(l, JK_LOG_DEBUG, "been here before, done"); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - - if (jk_get_worker_mx(props, p->name, (unsigned int *)&mem_config)) { - p->tomcat_mx = mem_config; - } - - if (jk_get_worker_ms(props, p->name, (unsigned int *)&mem_config)) { - p->tomcat_ms = mem_config; - } - - if (jk_get_worker_classpath(props, p->name, &str_config)) { - p->tomcat_classpath = jk_pool_strdup(&p->p, str_config); - } - - if (!p->tomcat_classpath) { - jk_log(l, JK_LOG_EMERG, "no classpath"); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - if (jk_get_worker_bridge_type(props, p->name, (unsigned int *)&btype)) { - p->bridge_type = btype; - } - - if (jk_get_worker_jvm_path(props, p->name, &str_config)) { - p->jvm_dll_path = jk_pool_strdup(&p->p, str_config); - } - - if (!p->jvm_dll_path || !jk_file_exists(p->jvm_dll_path)) { - jk_log(l, JK_LOG_EMERG, "no jvm_dll_path"); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - - if (jk_get_worker_cmd_line(props, p->name, &str_config)) { - p->tomcat_cmd_line = jk_pool_strdup(&p->p, str_config); - } - - if (jk_get_worker_stdout(props, p->name, &str_config)) { - p->stdout_name = jk_pool_strdup(&p->p, str_config); - } - - if (jk_get_worker_stderr(props, p->name, &str_config)) { - p->stderr_name = jk_pool_strdup(&p->p, str_config); - } - - if (jk_get_worker_sysprops(props, p->name, &str_config)) { - p->sysprops = jk_parse_sysprops(&p->p, str_config); - } - -#ifdef JNI_VERSION_1_2 - 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); - - jk_log(l, JK_LOG_WARNING, - "Worker '%s' is of type jni, which is deprecated " - "and will be removed in a future release.", - name ? name : "(null)"); - - 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; - - *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; - - 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) { - size_t 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_2 -static 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) -{ - size_t 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 */ - size_t 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; -} -#endif - -static 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); -} -#else -int JK_METHOD jni_worker_factory(jk_worker_t **w, - const char *name, jk_logger_t *l) -{ - jk_log(l, JK_LOG_WARNING, - "Worker '%s' is of type jni, which is deprecated " - "and will be removed in a future release.", - name ? name : "(null)"); - if (w) - *w = NULL; - return 0; -} -#endif /* JNI_VERSION_1_6 */ |