summaryrefslogtreecommitdiffstats
path: root/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_jni_worker.c
diff options
context:
space:
mode:
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.c1267
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 */