You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2002/01/12 06:06:06 UTC

cvs commit: jakarta-tomcat-connectors/jk/native2/common jk_jni_worker.c

costin      02/01/11 21:06:06

  Modified:    jk/native2/common jk_jni_worker.c
  Log:
  Jni worker, with starting the vm removed, a bit of cleanup, etc.
  
  Seems to work fine ( starting the vm, etc ) - need to get the rest working.
  ( and to start the real tomcats to do the work :-)
  
  Revision  Changes    Path
  1.11      +260 -1021 jakarta-tomcat-connectors/jk/native2/common/jk_jni_worker.c
  
  Index: jk_jni_worker.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_jni_worker.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- jk_jni_worker.c	16 Dec 2001 23:18:11 -0000	1.10
  +++ jk_jni_worker.c	12 Jan 2002 05:06:06 -0000	1.11
  @@ -55,313 +55,110 @@
    *                                                                           *
    * ========================================================================= */
   
  -/***************************************************************************
  - * Description: In process JNI worker                                      *
  - * Author:      Gal Shachor <sh...@il.ibm.com>                           *
  - * Based on:                                                               *
  - * Version:     $Revision: 1.10 $                                           *
  - ***************************************************************************/
  -
  -#if !defined(WIN32) && !defined(NETWARE)
  -#include <dlfcn.h>
  -#endif
  -
  -#include <jni.h>
  -
  -#include "jk_pool.h"
  -#include "jk_env.h"
  -
  -#if defined LINUX && defined APACHE2_SIGHACK
  -#include <pthread.h>
  -#include <signal.h>
  -#include <bits/signum.h>
  -#endif
  -
  -#ifdef NETWARE
  -#include <nwthread.h>
  -#include <nwadv.h>
  -#endif
  -#include "jk_logger.h"
  -#include "jk_service.h"
  -
  -#ifndef JNI_VERSION_1_1
  -#define JNI_VERSION_1_1 0x00010001
  -#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;
  -jint (JNICALL *jni_get_created_java_vms)(JavaVM **, int, int *) = NULL;
  -
  -#define JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/modules/server/JNIEndpoint")
  -/* #define JAVA_BRIDGE_CLASS_NAME ("org/apache/tomcat/service/JNIEndpoint")
  +/**
  + * In process JNI worker                                      
  + * @author:  Gal Shachor <sh...@il.ibm.com>
  + * @author: Costin Manolache
    */
   
  -static jk_worker_t *the_singleton_jni_worker = NULL;
  -
  -struct jni_worker {
  -
  -    int was_verified;
  -    int was_initialized;
  +#include "jk_vm.h"
  +#include "jk_registry.h"
  +#include "jni.h"
   
  -    jk_pool_t *pool;
  +/* default only, is configurable now */
  +#define JAVA_BRIDGE_CLASS_NAME ("org/apache/jk/common/ChannelJni")
   
  -    /*
  -     * JVM Object pointer.
  -     */
  -    JavaVM      *jvm;   
  -
  -    /*
  -     * [V] JNIEnv used for boostraping from validate -> init w/o an attach
  -     */
  -    JNIEnv	*tmp_env;
  +struct jni_worker_data {
   
  -    /*
  -     * Web Server to Java bridge, instance and class.
  -     */
  -    jobject     jk_java_bridge_object;
  +    jk_vm_t *vm;
  +    
       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 *className;
       char *tomcat_cmd_line;
  -
  -    /*
  -     * 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;
  -
  -int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool,
  -                                    void **result,
  -                                    char *type, char *name);
  -
  -static int load_jvm_dll(jk_env_t *env, jni_worker_t *p);
  -
  -static int open_jvm(jk_env_t *env, jni_worker_t *p,
  -                    JNIEnv **jniEnv);
  -
  -static int open_jvm1(jk_env_t *env, jni_worker_t *p,
  -                     JNIEnv **jniEnv);
  -
  -#ifdef JNI_VERSION_1_2
  -static int detect_jvm_version(jk_env_t *env);
  -
  -static int open_jvm2(jk_env_t *env, jni_worker_t *p,
  -                     JNIEnv **jniEnv);
  -#endif
  -
  -
  -static int get_bridge_object(jk_env_t *env, jni_worker_t *p,
  -                             JNIEnv *jniEnv );
  -
  -static int get_method_ids(jk_env_t *env, jni_worker_t *p,
  -                          JNIEnv *jniEnv);
  -
  -static JNIEnv *attach_to_jvm(jk_env_t *env, jni_worker_t *p);
  -
  -static void detach_from_jvm(jk_env_t *env, jni_worker_t *p);
   
  -static char **jk_parse_sysprops(jk_env_t *env, jk_pool_t *p, 
  -                                const char *sysprops);
  +typedef struct jni_worker_data jni_worker_data_t;
   
  -static int jk_file_exists(jk_env_t *env, const char *f);
   
  -static void jk_append_libpath(jk_env_t *env, jk_pool_t *p, 
  -                              const char *libpath);
  -
  -
  -#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
  -
  -static char **jk_parse_sysprops(jk_env_t *env, jk_pool_t *pool, 
  -                                const char *sysprops)
  -{
  -    char **rc = NULL;
  -
  -    if(pool && sysprops) {
  -        char *prps = pool->pstrdup(env, pool, sysprops);
  -        if(prps && strlen(prps)) {
  -            unsigned num_of_prps;
  -
  -            for(num_of_prps = 1; *sysprops ; sysprops++) {
  -                if('*' == *sysprops) {
  -                    num_of_prps++;
  -                }
  -            }            
  -
  -            rc = pool->alloc(env, pool, (num_of_prps + 1) * sizeof(char *));
  -            if(rc) {
  -                unsigned i = 0;
  -                char *tmp = strtok(prps, "*");
  -
  -                while(tmp && i < num_of_prps) {
  -                    rc[i] = tmp;
  -                    tmp = strtok(NULL, "*");
  -                    i++;
  -                }
  -                rc[i] = NULL;
  -            }
  -        }
  -    }
  -
  -    return rc;
  -}
  -
  -static int jk_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;
  -        }
  -    }
  -    return JK_FALSE;
  -}
  -
  -
  -static void jk_append_libpath(jk_env_t *env, jk_pool_t *pool, 
  -                              const char *libpath)
  +/** Static methods - much easier...
  + */
  +static int get_method_ids(jk_env_t *env, jni_worker_data_t *p, JNIEnv *jniEnv )
   {
  -    char *envVar = NULL;
  -    char *current = getenv(PATH_ENV_VARIABLE);
   
  -    if(current) {
  -        envVar = pool->alloc(env, pool, strlen(PATH_ENV_VARIABLE) + 
  -                          strlen(current) + 
  -                          strlen(libpath) + 5);
  -        if(envVar) {
  -            sprintf(envVar, "%s=%s%c%s", 
  -                    PATH_ENV_VARIABLE, 
  -                    libpath, 
  -                    PATH_SEPERATOR, 
  -                    current);
  -        }
  -    } else {
  -        envVar = pool->alloc(env, pool, strlen(PATH_ENV_VARIABLE) +
  -                             strlen(libpath) + 5);
  -        if(envVar) {
  -            sprintf(envVar, "%s=%s", PATH_ENV_VARIABLE, libpath);
  -        }
  +    p->jk_startup_method =
  +        (*jniEnv)->GetStaticMethodID(jniEnv, p->jk_java_bridge_class,
  +                                     "startup", 
  +               "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");
  +    
  +    if(!p->jk_startup_method) {
  +	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find startup()\n"); 
  +	return JK_FALSE;
       }
   
  -    if(envVar) {
  -        putenv(envVar);
  +    p->jk_service_method = (*jniEnv)->GetStaticMethodID(jniEnv,
  +                                                  p->jk_java_bridge_class, 
  +                                                  "service", 
  +                                               "(JJ)I");   
  +    if(!p->jk_service_method) {
  +	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find service()\n"); 
  +        return JK_FALSE;
       }
  +    
  +    p->jk_shutdown_method = (*jniEnv)->GetStaticMethodID(jniEnv,
  +                                                   p->jk_java_bridge_class, 
  +                                                   "shutdown", 
  +                                                   "()V");   
  +    if(!p->jk_shutdown_method) {
  +	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find shutdown()\n"); 
  +        return JK_FALSE;
  +    }    
  +    
  +    return JK_TRUE;
   }
   
  -static int JK_METHOD service(jk_env_t *env, jk_endpoint_t *e,
  -                             jk_ws_service_t *s,
  -                             int *is_recoverable_error)
  +static int JK_METHOD jni_worker_service(jk_env_t *env, jk_endpoint_t *e,
  +                                        jk_ws_service_t *s,
  +                                        int *is_recoverable_error)
   {
  -    jni_endpoint_t *p;
  +    JNIEnv *jniEnv;
       jint rc;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into service\n");
  -    if(!e || !e->endpoint_private || !s) {
  -	    env->l->jkLog(env, env->l, JK_LOG_ERROR,
  -                          "jni.service() NullPointerException\n");
  -	    return JK_FALSE;
  +    jni_worker_data_t *jniWorker;
  +    
  +    if(!e || !s) {
  +        env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                      "jni.service() NullPointerException\n");
  +        return JK_FALSE;
       }
   
  -    p = e->endpoint_private;
  -
       if(!is_recoverable_error) {
  -	    return JK_FALSE;
  +        env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                      "service() unrecoverable error status\n");
  +        return JK_FALSE;
       }
   
  -    if(!p->attached) { 
  +    env->l->jkLog(env, env->l, JK_LOG_INFO, "service() attaching to vm\n");
  +
  +    jniWorker=(jni_worker_data_t *)e->worker->worker_private;
  +    
  +    jniEnv=(JNIEnv *)e->endpoint_private;
  +    if(jniEnv==NULL) { /*! attached */
           /* Try to attach */
  -        if(!(p->env = attach_to_jvm(env, p->worker))) {
  +        jniEnv = jniWorker->vm->attach(env, jniWorker->vm);
  +            
  +        if(jniEnv == NULL ) {
               env->l->jkLog(env, env->l, JK_LOG_ERROR, "Attach failed\n");  
               /*   Is it recoverable ?? */
               *is_recoverable_error = JK_TRUE;
               return JK_FALSE;
           } 
  -        p->attached = JK_TRUE;
  +        e->endpoint_private = jniEnv;
       }
   
       /* we are attached now */
  @@ -375,60 +172,59 @@
       env->l->jkLog(env, env->l, JK_LOG_INFO,
                     "jni.service() calling Tomcat...\n");
   
  -    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.  */
  -                                    (jlong)(int)s,
  -                                    (jlong)(int)env);
  +    /* [V] For some reason gcc likes this pointer -> int -> jlong
  +       conversion, but not the direct pointer -> jlong conversion.
  +       I hope it's okay.  */
  +    rc = (*jniEnv)->CallStaticIntMethod( jniEnv,
  +                                         jniWorker->jk_java_bridge_class, 
  +                                         jniWorker->jk_service_method,
  +                                         (jlong)(int)s,
  +                                         (jlong)(int)env);
   
       /* [V] Righ now JNIEndpoint::service() only returns 1 or 0 */
       if(rc) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "In service, Tomcat returned OK, done\n");
  +        env->l->jkLog(env, env->l, JK_LOG_INFO, 
  +                      "service()  Tomcat returned OK, done\n");
           return JK_TRUE;
       } else {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In service, Tomcat FAILED!\n");
  +        env->l->jkLog(env, env->l, JK_LOG_INFO, 
  +                      "service() Tomcat FAILED!\n");
           return JK_FALSE;
       }
   }
   
  -static int JK_METHOD done(jk_env_t *env, jk_endpoint_t *e)
  +static int JK_METHOD jni_worker_done(jk_env_t *env, jk_endpoint_t *e)
   {
  -    jni_endpoint_t *p;
  -
  -    if(e==NULL || e->endpoint_private==NULL) {
  +    jni_worker_data_t *jniWorker;
  +    
  +    if(e==NULL) {
           env->l->jkLog(env, env->l, JK_LOG_ERROR,
                         "jni.done() NullPointerException\n");
           return JK_FALSE;
       }
   
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                  "jni.done()\n");
  +    jniWorker=(jni_worker_data_t *)e->worker->worker_private;
  +    
  +    /* XXX Don't detach if worker is reused per thread */
  +    e->endpoint_private=NULL;
  +    jniWorker->vm->detach( env, jniWorker->vm ); 
       
  -    p = e->endpoint_private;
  -
  -    if(p->attached) {
  -        detach_from_jvm(env, p->worker);
  -    }
  -
       e->pool->close( env, e->pool );
       env->l->jkLog(env, env->l, JK_LOG_INFO, 
                     "jni.done() ok\n");
       return JK_TRUE;
   }
   
  -static int JK_METHOD validate(jk_env_t *env, jk_worker_t *pThis,
  -                              jk_map_t *props, jk_workerEnv_t *we)
  +
  +static int JK_METHOD jni_worker_validate(jk_env_t *env, jk_worker_t *pThis,
  +                                         jk_map_t *props, jk_workerEnv_t *we)
   {
  -    jni_worker_t *p;
  +    jni_worker_data_t *jniWorker;
       int mem_config = 0;
       char *str_config = NULL;
  +    int rc;
       JNIEnv *jniEnv;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into validate\n");
  +    char *prefix;
   
       if(! pThis || ! pThis->worker_private) {
           env->l->jkLog(env, env->l, JK_LOG_ERROR,
  @@ -436,136 +232,99 @@
           return JK_FALSE;
       }
   
  -    p = pThis->worker_private;
  +    jniWorker = pThis->worker_private;
   
  -    if(p->was_verified) {
  -    	env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "validate, been here before, done\n");
  -        return JK_TRUE;
  -    }
  -
  -    mem_config= jk_map_getIntProp( env, props, "worker", p->name, "mx", -1 );
  -    if( mem_config != -1 ) {
  -        p->tomcat_mx = mem_config;
  -    }
  -
  -    mem_config= jk_map_getIntProp( env, props, "worker", p->name, "ms", -1 );
  -    if(mem_config != -1 ) {
  -        p->tomcat_ms = mem_config;
  -    }
  -
  -    str_config= jk_map_getStrProp( env, props, "worker", p->name,
  -                                   "class_path", NULL );
  -    if(str_config != NULL ) {
  -        p->tomcat_classpath = p->pool->pstrdup(env, p->pool, str_config);
  -    }
  -
  -    if(!p->tomcat_classpath) {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> no classpath\n");
  -        return JK_FALSE;
  -    }
  -
  -    str_config= jk_map_getStrProp( env, props, "worker", p->name, "jvm_lib",
  -                                   NULL );
  -    if(str_config != NULL ) {
  -        p->jvm_dll_path  = p->pool->pstrdup(env, p->pool, str_config);
  -    }
  -
  -    if(!p->jvm_dll_path || !jk_file_exists(env, p->jvm_dll_path)) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "Fail-> no jvm_dll_path\n");
  +    prefix=(char *)props->pool->alloc( env, props->pool,
  +                                       strlen( pThis->name ) + 10 );
  +    strcpy( prefix, "worker." );
  +    strcat( prefix, pThis->name );
  +    fprintf(stderr, "Prefix= %s\n", prefix );
  +    
  +    rc=jniWorker->vm->init(env, jniWorker->vm, props, prefix );
  +    if( rc!=JK_TRUE ) {
  +        env->l->jkLog(env, env->l, JK_LOG_ERROR,
  +                      "jni.validate() failed to load vm init params\n");
           return JK_FALSE;
       }
  +    
  +    jniWorker->className = jk_map_getStrProp( env, props, "worker",
  +                                              pThis->name,
  +                                              "class", JAVA_BRIDGE_CLASS_NAME);
   
  -    str_config= jk_map_getStrProp( env, props, "worker", p->name,
  -                                   "cmd_line", NULL ); 
  -    if(str_config != NULL ) {
  -        p->tomcat_cmd_line  = p->pool->pstrdup(env, p->pool, str_config);
  -    }
  -
  -    str_config=  jk_map_getStrProp( env, props, "worker", p->name, "stdout",
  -                                    NULL ); 
  -    if(str_config!= NULL ) {
  -        p->stdout_name  = p->pool->pstrdup(env, p->pool, str_config);
  -    }
  -
  -    str_config=  jk_map_getStrProp( env, props, "worker", p->name, "stderr",
  -                                    NULL ); 
  -    if(str_config!= NULL ) {
  -        p->stderr_name  = p->pool->pstrdup(env, p->pool, str_config);
  -    }
  -
  -    str_config=  jk_map_getStrProp( env, props, "worker", p->name,
  -                                    "sysprops", NULL ); 
  -    if(str_config!= NULL ) {
  -        p->sysprops  = jk_parse_sysprops(env, p->pool, str_config);
  -    }
  -
  -#ifdef JNI_VERSION_1_2
  -    str_config= jk_map_getStrProp( env, props, "worker", p->name, "java2opts",
  -                                   NULL );
  -    if( str_config != NULL ) {
  -    	/* l->jkLog(l, JK_LOG_DEBUG, "Got opts: %s\n", str_config); */
  -        p->java2opts = jk_parse_sysprops(env, p->pool, str_config);
  -    }
  -    mem_config= jk_map_getIntProp( env, props, "worker", p->name,
  -                                   "java2lax", -1 );
  -    if(mem_config != -1 ) {
  -        p->java2lax = mem_config ? JK_TRUE : JK_FALSE;
  -    }
  -#endif
  -
  -    str_config=  jk_map_getStrProp( env, props, "worker", p->name,
  -                                    "ld_path", NULL ); 
  -    if(str_config!= NULL ) {
  -        jk_append_libpath(env, p->pool, str_config);
  -    }
  +    jniWorker->tomcat_cmd_line = jk_map_getStrProp( env, props, "worker",
  +                                                    pThis->name,
  +                                                    "cmd_line", NULL ); 
   
  -    if(!load_jvm_dll(env, p)) {
  +    jniWorker->stdout_name= jk_map_getStrProp( env, props, "worker",
  +                                               pThis->name, "stdout", NULL ); 
  +    jniWorker->stderr_name= jk_map_getStrProp( env, props, "worker",
  +                                               pThis->name, "stderr", NULL );
  +    
  +    env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                  "jni.validate() cmd: %s %s %s %s\n",
  +                  jniWorker->className, jniWorker->tomcat_cmd_line,
  +                  jniWorker->stdout_name, jniWorker->stderr_name);
  +    
  +    /* Verify if we can load the vm XXX do we want this now ? */
  +    
  +    rc= jniWorker->vm->load(env, jniWorker->vm );
  +    
  +    if( !rc ) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Fail-> can't load jvm dll\n");
  +                      "jni.validated() Error - can't load jvm dll\n");
           /* [V] no detach needed here */
           return JK_FALSE;
       }
   
  -    if(!open_jvm(env, p, &jniEnv)) {
  +    rc = jniWorker->vm->open(env, jniWorker->vm );
  +    
  +    if( rc== JK_FALSE ) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG, "Fail-> can't open jvm\n");
           /* [V] no detach needed here */
           return JK_FALSE;
       }
   
  -    if(!get_bridge_object(env, p, jniEnv)) {
  +    jniEnv = (JNIEnv *)jniWorker->vm->attach( env, jniWorker->vm );
  +    
  +    jniWorker->jk_java_bridge_class =
  +        (*jniEnv)->FindClass(jniEnv, jniWorker->className );
  +
  +    if( jniWorker->jk_java_bridge_class == NULL ) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Fail-> can't get bridge object\n");
  +                      "Can't find class %s\n", str_config);
           /* [V] the detach here may segfault on 1.1 JVM... */
  -        detach_from_jvm(env, p);
  +        jniWorker->vm->detach(env,  jniWorker->vm);
           return JK_FALSE;
       }
  +    
  +    env->l->jkLog(env, env->l, JK_LOG_EMERG,
  +                  "Loaded %s\n", jniWorker->className);
   
  -    if(!get_method_ids(env, p, jniEnv)) {
  +    rc=get_method_ids(env, jniWorker, jniEnv);
  +    if( !rc ) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "Fail-> can't get method ids\n");
           /* [V] the detach here may segfault on 1.1 JVM... */
  -        detach_from_jvm(env, p);
  +        jniWorker->vm->detach(env, jniWorker->vm);
           return JK_FALSE;
       }
   
  -    p->was_verified = JK_TRUE;
  -    p->tmp_env = jniEnv;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Done validate\n");
  +    env->l->jkLog(env, env->l, JK_LOG_INFO, 
  +                  "jni.validate() ok\n");
   
       return JK_TRUE;
   }
   
  -static int JK_METHOD init(jk_env_t *env, jk_worker_t *pThis,
  +static int JK_METHOD jni_worker_init(jk_env_t *env, jk_worker_t *pThis,
                             jk_map_t *props, jk_workerEnv_t *we)
   {
  -    jni_worker_t *p;
  +    jni_worker_data_t *jniWorker;
       JNIEnv *jniEnv;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into init\n");
  +    jstring cmd_line = NULL;
  +    jstring stdout_name = NULL;
  +    jstring stderr_name = NULL;
  +    jint rc = 0;
  +    
   
       if(! pThis || ! pThis->worker_private) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
  @@ -573,87 +332,78 @@
           return JK_FALSE;
       }
   
  -    p = pThis->worker_private;
  +    jniWorker = pThis->worker_private;
   
  -    if(p->was_initialized) {
  +    if(pThis->workerEnv->vm != NULL ) {
           env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "init, done (been here!)\n");
  +                      "jni.init(), done (been here!)\n");
           return JK_TRUE;
       }
   
  -    if(!p->jvm ||
  -       !p->jk_java_bridge_object ||
  -       !p->jk_service_method     ||
  -       !p->jk_startup_method     ||
  -       !p->jk_shutdown_method) {
  +    if(!jniWorker->vm ||
  +       !jniWorker->jk_service_method     ||
  +       !jniWorker->jk_startup_method     ||
  +       !jniWorker->jk_shutdown_method) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "Fail-> worker not set completely\n");
           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 */
  +    env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.init()\n");
   
  -    /* if(env = attach_to_jvm(p,l)) { */
  -    if((jniEnv = p->tmp_env)) {
  -        jstring cmd_line = NULL;
  -        jstring stdout_name = NULL;
  -        jstring stderr_name = NULL;
  -        jint rc = 0;
  -
  -        if(p->tomcat_cmd_line) {
  -            cmd_line = (*jniEnv)->NewStringUTF(jniEnv, p->tomcat_cmd_line);
  -        }
  -        if(p->stdout_name) {
  -            stdout_name = (*jniEnv)->NewStringUTF(jniEnv, p->stdout_name);
  -        }
  -        if(p->stdout_name) {
  -            stderr_name = (*jniEnv)->NewStringUTF(jniEnv, p->stderr_name);
  -        }
  +    jniEnv=jniWorker->vm->attach(env, jniWorker->vm );
  +    if(jniEnv == NULL) {
  +        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  +                      "jni.init() can't attach to vm\n");
  +        return JK_FALSE;
  +    }
   
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In init, calling Tomcat to intialize itself...\n");
  +    if(jniWorker->tomcat_cmd_line) {
  +        cmd_line = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->tomcat_cmd_line);
  +    }
  +    if(jniWorker->stdout_name) {
  +        stdout_name = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->stdout_name);
  +    }
  +    if(jniWorker->stdout_name) {
  +        stderr_name = (*jniEnv)->NewStringUTF(jniEnv, jniWorker->stderr_name);
  +    }
  +    
  +    env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                  "jni.init() calling Tomcat to intialize itself...\n");
  +    
  +    rc = (*jniEnv)->CallStaticIntMethod(jniEnv,
  +                                        jniWorker->jk_java_bridge_class,
  +                                        jniWorker->jk_startup_method,
  +                                        cmd_line,
  +                                        stdout_name,
  +                                        stderr_name);
  +    
  +    jniWorker->vm->detach(env, jniWorker->vm); 
   
  -        rc = (*jniEnv)->CallIntMethod(jniEnv,
  -                                      p->jk_java_bridge_object,
  -                                      p->jk_startup_method,
  -                                      cmd_line,
  -                                      stdout_name,
  -                                      stderr_name);
  +    pThis->workerEnv->vm= jniWorker->vm;
           
  -        detach_from_jvm(env, p); 
  -        
  -        if(rc) {
  -            p->was_initialized = JK_TRUE;
  -            env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                          "In init, Tomcat initialized OK, done\n");
  -            return JK_TRUE;
  -        } else {
  -            env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                          "Fail-> could not initialize Tomcat\n");
  -            return JK_FALSE;
  -        }
  +    if(rc) {
  +        env->l->jkLog(env, env->l, JK_LOG_INFO, 
  +                      "jni.init() Tomcat initialized OK, done\n");
  +        return JK_TRUE;
       } else {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In init, FIXME: init didn't gen env from validate!\n");
  +        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  +                      "Fail-> could not initialize Tomcat\n");
           return JK_FALSE;
       }
   }
   
  -static int JK_METHOD get_endpoint(jk_env_t *env, jk_worker_t *pThis,
  -                                  jk_endpoint_t **pend)
  +static int JK_METHOD jni_worker_getEndpoint(jk_env_t *env, jk_worker_t *pThis,
  +                                            jk_endpoint_t **pend)
   {
       /* [V] This slow, needs replacement */
       jk_pool_t *endpointPool;
  -    jni_endpoint_t *e;
  +    jk_endpoint_t *e;
       
       endpointPool=pThis->pool->create( env, pThis->pool, HUGE_POOL_SIZE );
       
  -    e = (jni_endpoint_t *)endpointPool->calloc(env, endpointPool,
  -                                               sizeof(jni_endpoint_t));
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into get_endpoint\n");
  +    e = (jk_endpoint_t *)endpointPool->calloc(env, endpointPool,
  +                                              sizeof(jk_endpoint_t));
   
       if(!pThis || ! pThis->worker_private || !pend) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  @@ -667,625 +417,114 @@
           return JK_FALSE;
       }
   
  +    env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.get_endpoint()\n");
       /** XXX Fix the spaghetti */
  -    e->attached = JK_FALSE;
  -    e->env = NULL;
  -    e->worker = pThis->worker_private;
  -    e->endpoint.endpoint_private = e;
  -    e->endpoint.service = service;
  -    e->endpoint.done = done;
  -    e->endpoint.channelData = NULL;
  -    e->endpoint.pool=endpointPool;
  -    *pend = &e->endpoint;
  +
  +    e->worker = pThis;
  +    e->endpoint_private = NULL;
  +    e->service = jni_worker_service;
  +    e->done = jni_worker_done;
  +    e->channelData = NULL;
  +    e->pool=endpointPool;
  +    *pend = e;
       
       return JK_TRUE;
   }
   
  -static int JK_METHOD destroy(jk_env_t *env, jk_worker_t *_this)
  +static int JK_METHOD jni_worker_destroy(jk_env_t *env, jk_worker_t *_this)
   {
  -    jni_worker_t *p;
  +    jni_worker_data_t *jniWorker;
       JNIEnv *jniEnv;
   
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into destroy\n");
  -
       if(!_this  || ! _this->worker_private) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "In destroy, assert failed - invalid parameters\n");
           return JK_FALSE;
       }
   
  -    p = _this->worker_private;
  +    jniWorker = _this->worker_private;
   
  -    if(!p->jvm) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  +    if(!jniWorker->vm) {
  +        env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "In destroy, JVM not intantiated\n");
           return JK_FALSE;
       }
       
  -    if(!p->jk_java_bridge_object || ! p->jk_shutdown_method) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  +    if(! jniWorker->jk_shutdown_method) {
  +        env->l->jkLog(env, env->l, JK_LOG_EMERG,
                         "In destroy, Tomcat not intantiated\n");
           return JK_FALSE;
       }
   
  -    if((jniEnv = attach_to_jvm(env, p))) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "In destroy, shutting down Tomcat...\n");
  -        (*jniEnv)->CallVoidMethod(jniEnv,
  -                                  p->jk_java_bridge_object,
  -                                  p->jk_shutdown_method);
  -        detach_from_jvm(env, p);
  +    if((jniEnv = jniWorker->vm->attach(env, jniWorker->vm))) {
  +        env->l->jkLog(env, env->l, JK_LOG_INFO, 
  +                      "jni.destroy(), shutting down Tomcat...\n");
  +        (*jniEnv)->CallStaticVoidMethod(jniEnv,
  +                                  jniWorker->jk_java_bridge_class,
  +                                  jniWorker->jk_shutdown_method);
  +        jniWorker->vm->detach(env, jniWorker->vm);
       }
   
  -    p->pool->close(env, p->pool);
  +    _this->pool->close(env, _this->pool);
   
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Done destroy\n");
  +    env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.destroy() done\n");
   
       return JK_TRUE;
   }
   
  -int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool, void **result,
  -                                    char *type, char *name)
  +int JK_METHOD jk_worker_jni_factory(jk_env_t *env, jk_pool_t *pool,
  +                                    void **result,
  +                                    const char *type, const char *name)
   {
  -    jni_worker_t *_this;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Into jni_worker_factory\n");
  +    jk_worker_t *_this;
  +    jni_worker_data_t *jniData;
   
  -    if(!name) {
  +    if(name==NULL) {
           env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "In jni_worker_factory, assert failed - invalid parameters\n");
  +                      "jni.factory() NullPointerException name==null\n");
           return JK_FALSE;
       }
   
  -    if(the_singleton_jni_worker) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "In jni_worker_factory, instance already created\n");
  -        *result = the_singleton_jni_worker;
  -        return JK_TRUE;
  -    }
  +    /* No singleton - you can have multiple jni workers,
  +     running different bridges or starting different programs inprocess*/
   
  -    _this = (jni_worker_t *)pool->calloc(env, pool, sizeof(jni_worker_t ));
  -
  -    if(!_this) {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In jni_worker_factory, memory allocation error\n");
  -        return JK_FALSE;
  -    }
  -
  -    _this->pool=pool;
  +    _this=(jk_worker_t *)pool->calloc(env, pool, sizeof(jk_worker_t));
       
  -    _this->name = _this->pool->pstrdup(env, _this->pool, name);
  -
  -    if(!_this->name) {
  +    jniData = (jni_worker_data_t *)pool->calloc(env, pool,
  +                                                sizeof(jni_worker_data_t ));
  +    if(_this==NULL || jniData==NULL ) {
           env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In jni_worker_factory, memory allocation error\n");
  -        _this->pool->close(env, _this->pool);
  -        return JK_FALSE;
  -    }
  -
  -    _this->was_verified          = JK_FALSE;
  -    _this->was_initialized       = JK_FALSE;
  -    _this->jvm                   = NULL;
  -    _this->tmp_env               = NULL;
  -    _this->jk_java_bridge_object = NULL;
  -    _this->jk_java_bridge_class  = NULL;
  -    _this->jk_startup_method     = NULL;
  -    _this->jk_service_method     = NULL;
  -    _this->jk_shutdown_method    = NULL;
  -    _this->tomcat_cmd_line       = NULL;
  -    _this->tomcat_classpath      = NULL;
  -    _this->jvm_dll_path          = NULL;
  -    _this->tomcat_ms             = 0;
  -    _this->tomcat_mx             = 0;
  -    _this->sysprops              = NULL;
  -#ifdef JNI_VERSION_1_2
  -    _this->java2opts             = NULL;
  -    _this->java2lax              = JK_TRUE;
  -#endif
  -    _this->stdout_name           = NULL;
  -    _this->stderr_name           = NULL;
  -
  -    _this->worker.worker_private = _this;
  -    _this->worker.validate       = validate;
  -    _this->worker.init           = init;
  -    _this->worker.get_endpoint   = get_endpoint;
  -    _this->worker.destroy        = destroy;
  -
  -    *result = &_this->worker;
  -    the_singleton_jni_worker = &_this->worker;
  -    _this->worker.pool=pool;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, "Done jni_worker_factory\n");
  -    return JK_TRUE;
  -}
  -
  -static int load_jvm_dll(jk_env_t *env, jni_worker_t *p)
  -{
  -#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");
  -
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "Loaded all JNI procs\n");
  -
  -        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)
  -    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;
  -    }
  -#else 
  -    void *handle;
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into load_jvm_dll, load %s\n", p->jvm_dll_path);
  -
  -    handle = dlopen(p->jvm_dll_path, RTLD_NOW | RTLD_GLOBAL);
  -
  -    if(!handle) {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Can't load native library %s : %s\n", 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) {
  -    	    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                          "In load_jvm_dll, symbols resolved, done\n");
  -            return JK_TRUE;
  -        }
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Can't resolve JNI_CreateJavaVM or JNI_GetDefaultJavaVMInitArgs\n");
  -        dlclose(handle);
  -    }
  -#endif
  -    return JK_FALSE;
  -}
  -
  -static int open_jvm(jk_env_t *env, jni_worker_t *p,
  -                    JNIEnv **jniEnv)
  -{
  -#ifdef JNI_VERSION_1_2
  -    int jvm_version = detect_jvm_version(env);
  -
  -    switch(jvm_version) {
  -	    case JNI_VERSION_1_1:
  -	        return open_jvm1(env, p, jniEnv);
  -        case JNI_VERSION_1_2:
  -	        return open_jvm2(env, p, jniEnv);
  -	    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(env, p, jniEnv);
  -#endif
  -}
  -
  -static int open_jvm1(jk_env_t *env, jni_worker_t *p,
  -                     JNIEnv **jniEnv)
  -{
  -    JDK1_1InitArgs vm_args;  
  -    JNIEnv *penv = NULL;
  -    int err;
  -    *jniEnv = NULL;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into open_jvm1\n");
  -
  -    vm_args.version = JNI_VERSION_1_1;
  -
  -    if(0 != jni_get_default_java_vm_init_args(&vm_args)) {
  -    	env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Fail-> can't get default vm init args\n"); 
  -        return JK_FALSE;
  -    }
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "In open_jvm_dll, got default jvm args\n"); 
  -
  -    if(vm_args.classpath) {
  -        unsigned len = strlen(vm_args.classpath) + 
  -                       strlen(p->tomcat_classpath) + 
  -                       3;
  -        char *tmp = p->pool->alloc(env, p->pool, len);
  -        if(tmp) {
  -            sprintf(tmp, "%s%c%s", 
  -                    p->tomcat_classpath, 
  -                    PATH_SEPERATOR,
  -                    vm_args.classpath);
  -            p->tomcat_classpath = tmp;
  -        } else {
  -            env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                          "Fail-> allocation error for classpath\n"); 
  -            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) {
  -        vm_args.properties = p->sysprops;
  -    }
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                  "In open_jvm1, about to create JVM...\n");
  -    err=jni_create_java_vm(&(p->jvm), &penv, &vm_args);
  -
  -    if (JNI_EEXIST == err) {
  -        int vmCount;
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, "JVM alread instantiated."
  -                      "Trying to attach instead.\n");
  -        
  -        jni_get_created_java_vms(&(p->jvm), 1, &vmCount);
  -        if (NULL != p->jvm)
  -            penv = attach_to_jvm(env, p);
  -
  -        if (NULL != penv)
  -            err = 0;
  -    }
  -
  -    if(err != 0) {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Fail-> could not create JVM, code: %d \n", err); 
  -        return JK_FALSE;
  -    }
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "In open_jvm1, JVM created, done\n");
  -
  -    *jniEnv = penv;
  -
  -    return JK_TRUE;
  -}
  -
  -#ifdef JNI_VERSION_1_2
  -static int detect_jvm_version(jk_env_t *env)
  -{
  -    JNIEnv *jniEnv = NULL;
  -    JDK1_1InitArgs vm_args;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into detect_jvm_version\n");
  -
  -    /* [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)) {
  -    	env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Fail-> can't get default vm init args\n"); 
  -        return JK_FALSE;
  -    }
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "In detect_jvm_version, found: %X, done\n", vm_args.version);
  -
  -    return vm_args.version;
  -}
  -
  -static char* build_opt_str(jk_env_t *env, jk_pool_t *pool, 
  -                           char* opt_name, char* opt_value )
  -{
  -    unsigned len = strlen(opt_name) + strlen(opt_value) + 2;
  -
  -    /* [V] IMHO, these should not be deallocated as long as the JVM runs */
  -    char *tmp = pool->alloc(env, pool, len);
  -
  -    if(tmp) {
  -	    sprintf(tmp, "%s%s", opt_name, opt_value);
  -	    return tmp;
  -    } else {
  -	    env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                          "Fail-> build_opt_str allocation error for %s\n",
  -                          opt_name);
  -	    return NULL;
  -    }
  -}
  -
  -static char* build_opt_int(jk_env_t *env, jk_pool_t *pool, 
  -                           char* opt_name, int opt_value )
  -{
  -    /* [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 = pool->alloc(env, pool, len);
  -
  -    if(tmp) {
  -        sprintf(tmp, "%s%d", opt_name, opt_value);
  -        return tmp;
  -    } else {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Fail-> build_opt_int allocation error for %s\n",
  -                      opt_name);
  -        return NULL;
  -    }
  -}
  -
  -static int open_jvm2(jk_env_t *env, jni_worker_t *p, JNIEnv **jniEnv)
  -{
  -    JavaVMInitArgs vm_args;
  -    JNIEnv *penv;
  -    JavaVMOption options[100];
  -    int optn = 0, err;
  -    char* tmp;
  -    
  -    *jniEnv = NULL;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into open_jvm2\n");
  -
  -    vm_args.version = JNI_VERSION_1_2;
  -    vm_args.options = options;
  -
  -    if(p->tomcat_classpath) {
  -    	env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In open_jvm2, setting classpath to %s\n",
  -                      p->tomcat_classpath);
  -        tmp = build_opt_str(env, p->pool, "-Djava.class.path=",
  -                            p->tomcat_classpath);
  -        null_check(tmp);
  -        options[optn++].optionString = tmp;
  -    }
  -
  -    if(p->tomcat_mx) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In open_jvm2, setting max heap to %d\n", p->tomcat_mx);
  -    	tmp = build_opt_int(env, p->pool, "-Xmx", p->tomcat_mx);
  -        null_check(tmp);
  -        options[optn++].optionString = tmp;
  -    }
  -
  -    if(p->tomcat_ms) {
  -    	env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In open_jvm2, setting start heap to %d\n", p->tomcat_ms);
  -        tmp = build_opt_int(env, p->pool, "-Xms", p->tomcat_ms);
  -        null_check(tmp);
  -        options[optn++].optionString = tmp;
  -    }
  -
  -    if(p->sysprops) {
  -        int i = 0;
  -        while(p->sysprops[i]) {
  -            env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                          "In open_jvm2, setting %s\n", p->sysprops[i]);
  -            tmp = build_opt_str(env, p->pool, "-D", p->sysprops[i]);
  -            null_check(tmp);
  -            options[optn++].optionString = tmp;
  -            i++;
  -        }
  -    }
  -
  -    if(p->java2opts) {
  -        int i=0;
  -        
  -        while(p->java2opts[i]) {
  -            env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                          "In open_jvm2, using option: %s\n", p->java2opts[i]);
  -            /* Pass it "as is" */
  -            options[optn++].optionString = p->java2opts[i++];
  -        }
  -    }
  -
  -    vm_args.nOptions = optn;
  -    
  -    if(p->java2lax) {
  -    	env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In open_jvm2, the JVM will ignore unknown options\n");
  -        vm_args.ignoreUnrecognized = JNI_TRUE;
  -    } else {
  -    	env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                      "In open_jvm2, the JVM will FAIL if it finds unknown options\n");
  -        vm_args.ignoreUnrecognized = JNI_FALSE;
  -    }
  -    
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                  "In open_jvm2, about to create JVM...\n");
  -
  -    if((err=jni_create_java_vm(&(p->jvm), &penv, &vm_args)) != 0) {
  -    	env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Fail-> could not create JVM, code: %d \n", err); 
  +                      "jni.factory() OutOfMemoryException \n");
           return JK_FALSE;
       }
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG,
  -                  "In open_jvm2, JVM created, done\n");
   
  -    *jniEnv = penv;
  +    _this->worker_private=jniData;
   
  -    return JK_TRUE;
  -}
  -#endif
  -
  -static int get_bridge_object(jk_env_t *env, jni_worker_t *p, JNIEnv *jniEnv)
  -{
  -    jmethodID  constructor_method_id;
  -
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into get_bridge_object\n");
  -
  -    p->jk_java_bridge_class = (*jniEnv)->FindClass(jniEnv, JAVA_BRIDGE_CLASS_NAME);
  -    if(!p->jk_java_bridge_class) {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Can't find class %s\n", JAVA_BRIDGE_CLASS_NAME);
  -        return JK_FALSE;
  -    }
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "In get_bridge_object, loaded %s bridge class\n",
  -                  JAVA_BRIDGE_CLASS_NAME);
  -
  -    constructor_method_id = (*jniEnv)->GetMethodID(jniEnv,
  -                                                   p->jk_java_bridge_class,
  -                                                   "<init>", /* method name */
  -                                                   "()V");   /* method sign */
  -    if(!constructor_method_id) {
  -        p->jk_java_bridge_class = NULL;
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Can't find constructor\n");
  -        return JK_FALSE;
  -    }
  -
  -    p->jk_java_bridge_object = (*jniEnv)->NewObject(jniEnv,
  -                                                    p->jk_java_bridge_class,
  -                                                    constructor_method_id);
  -    if(! p->jk_java_bridge_object) {
  -        p->jk_java_bridge_class = NULL;
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG, 
  -                      "Can't create new bridge object\n");
  -        return JK_FALSE;
  -    }
  +    _this->pool=pool;
  +    _this->name = _this->pool->pstrdup(env, _this->pool, name);
   
  -    p->jk_java_bridge_object =
  -        (jobject)(*jniEnv)->NewGlobalRef(jniEnv, p->jk_java_bridge_object);
  +    /* XXX split it in VM11 and VM12 util */
  +    jk_vm_factory( env, pool, &jniData->vm, "vm", "default" );
       
  -    if(! p->jk_java_bridge_object) {
  -        env->l->jkLog(env, env->l, JK_LOG_EMERG,
  -                      "Can't create global ref to bridge object\n");
  -        p->jk_java_bridge_class = NULL;
  -        p->jk_java_bridge_object = NULL;
  -        return JK_FALSE;
  -    }
  +    jniData->jk_java_bridge_class  = NULL;
  +    jniData->jk_startup_method     = NULL;
  +    jniData->jk_service_method     = NULL;
  +    jniData->jk_shutdown_method    = NULL;
  +
  +    jniData->tomcat_cmd_line       = NULL;
  +    jniData->stdout_name           = NULL;
  +    jniData->stderr_name           = NULL;
  +
  +    _this->validate       = jni_worker_validate;
  +    _this->init           = jni_worker_init;
  +    _this->get_endpoint   = jni_worker_getEndpoint;
  +    _this->destroy        = jni_worker_destroy;
   
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "In get_bridge_object, bridge built, done\n");
  -    return JK_TRUE;
  -}
  +    *result = _this;
   
  -static int get_method_ids(jk_env_t *env, jni_worker_t *p, JNIEnv *jniEnv )
  -{
  -    p->jk_startup_method =
  -        (*jniEnv)->GetMethodID(jniEnv, p->jk_java_bridge_class, "startup", 
  -                               "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I");  
  -    if(!p->jk_startup_method) {
  -	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find startup()\n"); 
  -	return JK_FALSE;
  -    }
  +    env->l->jkLog(env, env->l, JK_LOG_INFO,
  +                  "jni.worker_factory() done\n");
   
  -    p->jk_service_method = (*jniEnv)->GetMethodID(jniEnv,
  -                                                  p->jk_java_bridge_class, 
  -                                                  "service", 
  -                                               "(JJ)I");   
  -    if(!p->jk_service_method) {
  -	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find service()\n"); 
  -        return JK_FALSE;
  -    }
  -    
  -    p->jk_shutdown_method = (*jniEnv)->GetMethodID(jniEnv,
  -                                                   p->jk_java_bridge_class, 
  -                                                   "shutdown", 
  -                                                   "()V");   
  -    if(!p->jk_shutdown_method) {
  -	env->l->jkLog(env, env->l, JK_LOG_EMERG, "Can't find shutdown()\n"); 
  -        return JK_FALSE;
  -    }    
  -    
       return JK_TRUE;
   }
   
  -static JNIEnv *attach_to_jvm(jk_env_t *env, jni_worker_t *p)
  -{
  -    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  */
  -    env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                  "Into attach_to_jvm\n");
  -
  -#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)) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "In attach_to_jvm, attached ok\n");
  -        return rc;
  -    }
  -    env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                  "In attach_to_jvm, cannot attach thread to JVM.\n");
  -    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(jk_env_t *env, jni_worker_t *p)
  -{
  -    if(!p->jvm || !(*(p->jvm))) {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In detach_from_jvm, cannot detach from NULL JVM.\n");
  -    }
  -
  -    if(0 == (*(p->jvm))->DetachCurrentThread(p->jvm)) {
  -        env->l->jkLog(env, env->l, JK_LOG_DEBUG, 
  -                      "In detach_from_jvm, detached ok\n");
  -    } else {
  -        env->l->jkLog(env, env->l, JK_LOG_ERROR, 
  -                      "In detach_from_jvm, cannot detach from JVM.\n");
  -    }
  -}
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>