📄 jk_vm_default.c
字号:
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2002 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * notice, this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <apache@apache.org>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY * * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * * POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= * * * * This software consists of voluntary contributions made by many indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= *//** * JNI utils. This is now organized as a class with virtual methods. * This will allow a future split based on VM type, and simplification * of the code ( no more #ifdefs, but different objects for different VMs). * * It should also allow to better work around VMs and support more * ( I assume kaffe will need some special tricks, 1.4 will be different * than 1.1 and 1.2, IBM vms have their own paths, etc ). * * That's future - for now we use the current ugly code ( result * of few years of workarounds ). The refactoring should be done before adding * anything new. * * @author: Gal Shachor <shachor@il.ibm.com> * @author: Costin Manolache */#include "jk_workerEnv.h"#include "jk_env.h"#include "jk_bean.h"#ifdef HAVE_JNI#include "jk_global.h"#include "jk_vm.h"#include "jk_config.h"#if defined LINUX && defined APACHE2_SIGHACK#include <pthread.h>#include <signal.h>#include <bits/signum.h>#endif#if !defined(WIN32) && !defined(NETWARE)#include <dlfcn.h>#endif#ifdef NETWARE#include <nwthread.h>#include <nwadv.h>#endif#include <jni.h>#ifdef APR_HAS_DSO#include "apr_dso.h"#endif#ifndef JNI_VERSION_1_2#warning -------------------------------------------------------#warning JAVA 1.1 IS NO LONGER SUPPORTED #warning -------------------------------------------------------int JK_METHOD jk2_vm_factory(jk_env_t *env, jk_pool_t *pool, jk_bean_t *result, char *type, char *name){ return JK_ERR;}#else#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_FALSEstatic int jk2_detect_jvm_version(jk_env_t *env);static int jk2_open_jvm2(jk_env_t *env, jk_vm_t *p);jint (JNICALL *jni_get_default_java_vm_init_args)(void *) = NULL;jint (JNICALL *jni_create_java_vm)(JavaVM **, JNIEnv **, void *) = NULL;jint (JNICALL *jni_get_created_java_vms)(JavaVM **, int, int *) = NULL;/* Guessing - try all those to find the right dll */static const char *defaultVM_PATH[]={ "${JAVA_HOME}${fs}jre${fs}bin${fs}classic${fs}libjvm.${so}", "${JAVA_HOME}${fs}jre${fs}bin${fs}client${fs}jvm.${so}", "${JAVA_HOME}${fs}jre${fs}lib${fs}${arch}${fs}classic${fs}libjvm.${so}", "${JAVA_HOME}${fs}jre${fs}lib${fs}${arch}${fs}client${fs}libjvm.${so}", "${JAVA_HOME}${fs}jre${fs}bin${fs}classic${fs}jvm.${so}", NULL};#if defined LINUX && defined APACHE2_SIGHACKstatic void jk2_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 jk2_print_signals( sigset_t *sset) { int sig; for (sig = 1; sig < 20; sig++) { if (sigismember(sset, sig)) {printf( " %d", sig);} } printf( "\n");}#endif/* JVM hooks */static int jk2_jni_exit_signaled = JK_FALSE;static int jk2_jni_exit_code = 0;static int jk2_jni_abort_signaled = JK_FALSE;static void jk2_jni_exit_hook(int code){ jk2_jni_exit_signaled = JK_TRUE; jk2_jni_abort_signaled = JK_TRUE; jk2_jni_exit_code = code;#ifdef DEBUG fprintf(stderr, "JVM exit hook called %d\n", code);#endif}static void jk2_jni_abort_hook(){ jk2_jni_abort_signaled = JK_TRUE; #ifdef DEBUG fprintf(stderr, "JVM abort hook\n");#endif} /** Load the VM. Must be called after init. */static int jk2_vm_loadJvm(jk_env_t *env, jk_vm_t *jkvm){#if defined(HAS_APR) && defined(APR_HAS_DSO) apr_dso_handle_t *dsoHandle; apr_status_t rc; apr_pool_t *aprPool; aprPool= (apr_pool_t *)env->getAprPool( env ); if( aprPool==NULL ) return JK_FALSE; /* XXX How do I specify RTLD_NOW and RTLD_GLOBAL ? */ rc=apr_dso_load( &dsoHandle, jkvm->jvm_dll_path, aprPool ); if(rc == APR_SUCCESS ) { rc= apr_dso_sym( (apr_dso_handle_sym_t *)&jni_create_java_vm, dsoHandle, "JNI_CreateJavaVM"); } if( rc == APR_SUCCESS ) { rc=apr_dso_sym( (apr_dso_handle_sym_t *)&jni_get_default_java_vm_init_args, dsoHandle, "JNI_GetDefaultJavaVMInitArgs"); } if( rc == APR_SUCCESS ) { rc=apr_dso_sym( (apr_dso_handle_sym_t *)&jni_get_created_java_vms, dsoHandle, "JNI_GetCreatedJavaVMs"); } if( rc!= APR_SUCCESS ) { char buf[256]; env->l->jkLog(env, env->l, JK_LOG_ERROR, "Can't load native library %s : %s\n", jkvm->jvm_dll_path, apr_dso_error(dsoHandle, buf, 256)); return JK_ERR; } if(jni_create_java_vm == NULL || jni_get_default_java_vm_init_args == NULL || jni_get_created_java_vms == NULL ) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "jni.loadJvm() Can't resolve symbols %s\n", jkvm->jvm_dll_path ); apr_dso_unload( dsoHandle); return JK_ERR; } if( jkvm->mbean->debug > 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "jni.loadJvm() %s symbols resolved\n", jkvm->jvm_dll_path); return JK_OK;#else env->l->jkLog(env, env->l, JK_LOG_ERROR, "Can't load jvm, no apr support %s\n"); return JK_ERR;#endif }static void *jk2_vm_attach(jk_env_t *env, jk_vm_t *jkvm){ JNIEnv *rc = NULL; int err; JavaVM *jvm = (JavaVM *)jkvm->jvm; if (jvm == NULL || jk2_jni_abort_signaled) return NULL; #if defined LINUX && defined APACHE2_SIGHACK /* [V] This message is important. If there are signal mask issues, * * the JVM usually hangs when a new thread tries to attach to it */ /* XXX do we need to do that on _each_ attach or only when we create the vm ??? */ /* jk2_linux_signal_hack(); */#endif err= (*jvm)->GetEnv( jvm, (void **)&rc, JNI_VERSION_1_2 ); /* If the current thread is allready attached to the VM return the appropriate interface. There is no need to call the AttachCurrentThread. */ if( err == 0) { if( jkvm->mbean->debug >= 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "vm.attach() allready attached\n"); return (void *)rc; } /* The error code is either JNI_OK (allready attached) or JNI_EDETACHED. Othere possibility is that specified version is not supported, and the returned err in that case is JNI_EVERSION. */ if( err != JNI_EDETACHED) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "vm.attach() GetEnv failed %d\n", err); return NULL; } err = (*jvm)->AttachCurrentThread(jvm, (void **) &rc, NULL); if( err != 0 ) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "vm.attach() error %d\n", err); return NULL; } if( jkvm->mbean->debug >= 0 ) env->l->jkLog(env, env->l, JK_LOG_DEBUG, "vm.attach() ok\n"); return (void *)rc;}static void jk2_vm_detach(jk_env_t *env, jk_vm_t *jkvm){ int err; JavaVM *jvm = (JavaVM *)jkvm->jvm; if (jvm == NULL || jk2_jni_abort_signaled) { return; } err= (*jvm)->DetachCurrentThread(jvm); if(err == 0 ) { env->l->jkLog(env, env->l, JK_LOG_INFO, "vm.detach() ok\n"); } else { env->l->jkLog(env, env->l, JK_LOG_ERROR, "vm.detach() cannot detach from JVM.\n"); }}static int jk2_file_exists(jk_env_t *env, const char *f){ if(f) { struct stat st; if((0 == stat(f, &st)) && (st.st_mode & S_IFREG)) { return JK_TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -