alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Tomcat example source code file (jnilib.c)

This example Tomcat source code file (jnilib.c) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Tomcat tags/keywords

apr_success, jni_err, jni_err, jni_true, jni_true, library, null, null, tcn_declare, tcn_implement_call, tcn_implement_call, tcn_load_class, unreferenced, unreferenced_stdargs

The Tomcat jnilib.c source code

/* 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.
 */

/*
 *
 * @author Mladen Turk
 * @version $Revision: 524383 $, $Date: 2007-03-31 09:34:01 +0200 (sam., 31 mars 2007) $
 */

#include "tcn.h"
#include "apr_version.h"
#include "apr_file_io.h"
#include "apr_mmap.h"
#include "apr_atomic.h"

#include "tcn_version.h"

#ifdef TCN_DO_STATISTICS
extern void sp_poll_dump_statistics();
extern void sp_network_dump_statistics();
extern void ssl_network_dump_statistics();
#endif

apr_pool_t *tcn_global_pool = NULL;
static JavaVM     *tcn_global_vm = NULL;

static jclass    jString_class;
static jclass    jFinfo_class;
static jclass    jAinfo_class;
static jmethodID jString_init;
static jmethodID jString_getBytes;

int tcn_parent_pid = 0;

/* Called by the JVM when APR_JAVA is loaded */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
{
    JNIEnv *env;
    apr_version_t apv;
    int apvn;

    UNREFERENCED(reserved);
    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_4)) {
        return JNI_ERR;
    }
    tcn_global_vm = vm;

    /* Before doing anything else check if we have a valid
     * APR version. We need version 1.2.1 as minimum.
     */
    apr_version(&apv);
    apvn = apv.major * 1000 + apv.minor * 100 + apv.patch;
    if (apvn < 1201) {
        tcn_Throw(env, "Unupported APR version (%s)",
                  apr_version_string());
        return JNI_ERR;
    }


    /* Initialize global java.lang.String class */
    TCN_LOAD_CLASS(env, jString_class, "java/lang/String", JNI_ERR);
    TCN_LOAD_CLASS(env, jFinfo_class, TCN_FINFO_CLASS, JNI_ERR);
    TCN_LOAD_CLASS(env, jAinfo_class, TCN_AINFO_CLASS, JNI_ERR);

    TCN_GET_METHOD(env, jString_class, jString_init,
                   "<init>", "([B)V", JNI_ERR);
    TCN_GET_METHOD(env, jString_class, jString_getBytes,
                   "getBytes", "()[B", JNI_ERR);

    if(tcn_load_finfo_class(env, jFinfo_class) != APR_SUCCESS)
        return JNI_ERR;
    if(tcn_load_ainfo_class(env, jAinfo_class) != APR_SUCCESS)
        return JNI_ERR;
#ifdef WIN32
    {
        char *ppid = getenv(TCN_PARENT_IDE);
        if (ppid)
            tcn_parent_pid = atoi(ppid);
    }
#else
    tcn_parent_pid = getppid();
#endif

    return  JNI_VERSION_1_4;
}


/* Called by the JVM before the APR_JAVA is unloaded */
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
{
    JNIEnv *env;

    UNREFERENCED(reserved);

    if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2)) {
        return;
    }
    if (tcn_global_pool) {
        TCN_UNLOAD_CLASS(env, jString_class);
        TCN_UNLOAD_CLASS(env, jFinfo_class);
        TCN_UNLOAD_CLASS(env, jAinfo_class);
        apr_terminate();
    }
}

jstring tcn_new_stringn(JNIEnv *env, const char *str, size_t l)
{
    jstring result;
    jbyteArray bytes = 0;
    size_t len = l;

    if (!str)
        return NULL;
    if ((*env)->EnsureLocalCapacity(env, 2) < 0) {
        return NULL; /* out of memory error */
    }
    if (l < 0)
        len = strlen(str);
    bytes = (*env)->NewByteArray(env, (jsize)len);
    if (bytes != NULL) {
        (*env)->SetByteArrayRegion(env, bytes, 0, (jint)len, (jbyte *)str);
        result = (*env)->NewObject(env, jString_class, jString_init, bytes);
        (*env)->DeleteLocalRef(env, bytes);
        return result;
    } /* else fall through */
    return NULL;
}

jbyteArray tcn_new_arrayb(JNIEnv *env, const unsigned char *data, size_t len)
{
    jbyteArray bytes = (*env)->NewByteArray(env, (jsize)len);
    if (bytes != NULL) {
        (*env)->SetByteArrayRegion(env, bytes, 0, (jint)len, (jbyte *)data);
    }
    return bytes;
}

jobjectArray tcn_new_arrays(JNIEnv *env, size_t len)
{
    return (*env)->NewObjectArray(env, (jsize)len, jString_class, NULL);
}

jstring tcn_new_string(JNIEnv *env, const char *str)
{
    if (!str)
        return NULL;
    else
        return (*env)->NewStringUTF(env, str);
}

char *tcn_get_string(JNIEnv *env, jstring jstr)
{
    jbyteArray bytes = NULL;
    jthrowable exc;
    char *result = NULL;

    if ((*env)->EnsureLocalCapacity(env, 2) < 0) {
        return NULL; /* out of memory error */
    }
    bytes = (*env)->CallObjectMethod(env, jstr, jString_getBytes);
    exc = (*env)->ExceptionOccurred(env);
    if (!exc) {
        jint len = (*env)->GetArrayLength(env, bytes);
        result = (char *)malloc(len + 1);
        if (result == NULL) {
            TCN_THROW_OS_ERROR(env);
            (*env)->DeleteLocalRef(env, bytes);
            return 0;
        }
        (*env)->GetByteArrayRegion(env, bytes, 0, len, (jbyte *)result);
        result[len] = '\0'; /* NULL-terminate */
    }
    else {
        (*env)->DeleteLocalRef(env, exc);
    }
    (*env)->DeleteLocalRef(env, bytes);

    return result;
}

char *tcn_strdup(JNIEnv *env, jstring jstr)
{
    char *result = NULL;
    const char *cjstr;

    cjstr = (const char *)((*env)->GetStringUTFChars(env, jstr, 0));
    if (cjstr) {
        result = strdup(cjstr);
        (*env)->ReleaseStringUTFChars(env, jstr, cjstr);
    }
    return result;
}

char *tcn_pstrdup(JNIEnv *env, jstring jstr, apr_pool_t *pool)
{
    char *result = NULL;
    const char *cjstr;

    cjstr = (const char *)((*env)->GetStringUTFChars(env, jstr, 0));
    if (cjstr) {
        result = apr_pstrdup(pool, cjstr);
        (*env)->ReleaseStringUTFChars(env, jstr, cjstr);
    }
    return result;
}

TCN_IMPLEMENT_CALL(jboolean, Library, initialize)(TCN_STDARGS)
{

    UNREFERENCED_STDARGS;
    if (!tcn_global_pool) {
        apr_initialize();
        if (apr_pool_create(&tcn_global_pool, NULL) != APR_SUCCESS) {
            return JNI_FALSE;
        }
        apr_atomic_init(tcn_global_pool);
    }
    return JNI_TRUE;
}

TCN_IMPLEMENT_CALL(void, Library, terminate)(TCN_STDARGS)
{

    UNREFERENCED_STDARGS;
    if (tcn_global_pool) {        
        apr_pool_t *p = tcn_global_pool;
        tcn_global_pool = NULL;
#ifdef TCN_DO_STATISTICS
        fprintf(stderr, "APR Statistical data ....\n");
#endif
        apr_pool_destroy(p);
#ifdef TCN_DO_STATISTICS
        sp_poll_dump_statistics();
        sp_network_dump_statistics();
        ssl_network_dump_statistics();
        fprintf(stderr, "APR Terminated\n");
#endif
        apr_terminate();
    }
}

TCN_IMPLEMENT_CALL(jlong, Library, globalPool)(TCN_STDARGS)
{
    UNREFERENCED_STDARGS;
    return P2J(tcn_global_pool);
}

TCN_IMPLEMENT_CALL(jint, Library, version)(TCN_STDARGS, jint what)
{
    apr_version_t apv;

    UNREFERENCED_STDARGS;
    apr_version(&apv);

    switch (what) {
        case 0x01:
            return TCN_MAJOR_VERSION;
        break;
        case 0x02:
            return TCN_MINOR_VERSION;
        break;
        case 0x03:
            return TCN_PATCH_VERSION;
        break;
        case 0x04:
#ifdef TCN_IS_DEV_VERSION
            return 1;
#else
            return 0;
#endif
        break;
        case 0x11:
            return apv.major;
        break;
        case 0x12:
            return apv.minor;
        break;
        case 0x13:
            return apv.patch;
        break;
        case 0x14:
            return apv.is_dev;
        break;
    }
    return 0;
}

TCN_IMPLEMENT_CALL(jstring, Library, versionString)(TCN_STDARGS)
{
    UNREFERENCED(o);
    return AJP_TO_JSTRING(TCN_VERSION_STRING);
}

TCN_IMPLEMENT_CALL(jstring, Library, aprVersionString)(TCN_STDARGS)
{
    UNREFERENCED(o);
    return AJP_TO_JSTRING(apr_version_string());
}

TCN_IMPLEMENT_CALL(jboolean, Library, has)(TCN_STDARGS, jint what)
{
    jboolean rv = JNI_FALSE;
    UNREFERENCED_STDARGS;
    switch (what) {
        case 0:
#if APR_HAVE_IPV6
            rv = JNI_TRUE;
#endif
        break;
        case 1:
#if APR_HAS_SHARED_MEMORY
            rv = JNI_TRUE;
#endif
        break;
        case 2:
#if APR_HAS_THREADS
            rv = JNI_TRUE;
#endif
        break;
        case 3:
#if APR_HAS_SENDFILE
            rv = JNI_TRUE;
#endif
        break;
        case 4:
#if APR_HAS_MMAP
            rv = JNI_TRUE;
#endif
        break;
        case 5:
#if APR_HAS_FORK
            rv = JNI_TRUE;
#endif
        break;
        case 6:
#if APR_HAS_RANDOM
            rv = JNI_TRUE;
#endif
        break;
        case 7:
#if APR_HAS_OTHER_CHILD
            rv = JNI_TRUE;
#endif
        break;
        case 8:
#if APR_HAS_DSO
            rv = JNI_TRUE;
#endif
        break;
        case 9:
#if APR_HAS_SO_ACCEPTFILTER
            rv = JNI_TRUE;
#endif
        break;
        case 10:
#if APR_HAS_UNICODE_FS
            rv = JNI_TRUE;
#endif
        break;
        case 11:
#if APR_HAS_PROC_INVOKED
            rv = JNI_TRUE;
#endif
        break;
        case 12:
#if APR_HAS_USER
            rv = JNI_TRUE;
#endif
        break;
        case 13:
#if APR_HAS_LARGE_FILES
            rv = JNI_TRUE;
#endif
        break;
        case 14:
#if APR_HAS_XTHREAD_FILES
            rv = JNI_TRUE;
#endif
        break;
        case 15:
#if APR_HAS_OS_UUID
            rv = JNI_TRUE;
#endif
        break;
        case 16:
#if APR_IS_BIGENDIAN
            rv = JNI_TRUE;
#endif
        break;

        case 17:
#if APR_FILES_AS_SOCKETS
            rv = JNI_TRUE;
#endif
        break;
        case 18:
#if APR_CHARSET_EBCDIC
            rv = JNI_TRUE;
#endif
        break;
        case 19:
#if APR_TCP_NODELAY_INHERITED
            rv = JNI_TRUE;
#endif
        break;
        case 20:
#if APR_O_NONBLOCK_INHERITED
            rv = JNI_TRUE;
#endif
        break;
    }
    return rv;
}

TCN_IMPLEMENT_CALL(jint, Library, size)(TCN_STDARGS, jint what)
{

    UNREFERENCED_STDARGS;

    switch (what) {
        case 1:
            return APR_SIZEOF_VOIDP;
        break;
        case 2:
            return APR_PATH_MAX;
        break;
        case 3:
            return APRMAXHOSTLEN;
        break;
        case 4:
            return APR_MAX_IOVEC_SIZE;
        break;
        case 5:
            return APR_MAX_SECS_TO_LINGER;
        break;
        case 6:
            return APR_MMAP_THRESHOLD;
        break;
        case 7:
            return APR_MMAP_LIMIT;
        break;

    }
    return 0;
}

TCN_DECLARE(apr_pool_t *) tcn_get_global_pool()
{
    if (!tcn_global_pool) {
        if (apr_pool_create(&tcn_global_pool, NULL) != APR_SUCCESS) {
            return NULL;
        }
        apr_atomic_init(tcn_global_pool);
    }
    return tcn_global_pool;
}

TCN_DECLARE(jclass) tcn_get_string_class()
{
    return jString_class;
}

TCN_DECLARE(JavaVM *) tcn_get_java_vm()
{
    return tcn_global_vm;
}

TCN_DECLARE(jint) tcn_get_java_env(JNIEnv **env)
{
    if ((*tcn_global_vm)->GetEnv(tcn_global_vm, (void **)env,
                                 JNI_VERSION_1_4)) {
        return JNI_ERR;
    }
    return JNI_OK;
}

Other Tomcat examples (source code examples)

Here is a short list of links related to this Tomcat jnilib.c source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.