⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_jni_worker.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:
    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);

    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;
    private_data->worker.retries = JK_RETRIES;

    *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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -