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

📄 jk_jni_worker.c

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

⌨️ 快捷键说明

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