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/26 07:48:17 UTC
cvs commit: jakarta-tomcat-connectors/jk/native2/common jk_worker_jni.c jk_jni_worker.c
costin 02/01/25 22:48:17
Added: jk/native2/common jk_worker_jni.c
Removed: jk/native2/common jk_jni_worker.c
Log:
Removed the old jni worker. It had a number of problems, and was pretty hard to
improve.
The new worker is a subset - it only deals with starting an embeded VM and running
a startup/shutdown method when needed.
It relies on all the improvements in the new jk_vm, which deals with all the
dirty details of creating a vm - and more importantly does a lot of guessing
( for a 'mainstream' vm, all you have to set is LD_LIBRARY_PATH and JAVA_HOME
before starting apache - all else is detected ).
You can of course start different programs ( a single vm will be used tough ).
All the request forwarding is in the jni channel.
Revision Changes Path
1.1 jakarta-tomcat-connectors/jk/native2/common/jk_worker_jni.c
Index: jk_worker_jni.c
===================================================================
/* ========================================================================= *
* *
* The Apache Software License, Version 1.1 *
* *
* Copyright (c) 1999-2001 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 <ap...@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/>. *
* *
* ========================================================================= */
/**
* In process JNI worker. It'll call an arbitrary java class's main method
* with given parameters and set a pointer to the java vm in the workerEnv.
* ( XXX and an optional set method to pass env, workerEnv pointers )
*
* @author: Gal Shachor <sh...@il.ibm.com>
* @author: Costin Manolache
*/
#include "jk_vm.h"
#include "jk_registry.h"
#include "jni.h"
/* default only, will be configurable */
#define JAVA_BRIDGE_CLASS_NAME ("org/apache/jk/server/JniMain")
struct jni_worker_data {
jk_vm_t *vm;
jclass jk_java_bridge_class;
jmethodID jk_startup_method;
jmethodID jk_shutdown_method;
char *className;
char *tomcat_cmd_line;
char *stdout_name;
char *stderr_name;
};
typedef struct jni_worker_data jni_worker_data_t;
/** Static methods - much easier...
*/
static int get_method_ids(jk_env_t *env, jni_worker_data_t *p, JNIEnv *jniEnv )
{
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;
}
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 jni_worker_service(jk_env_t *env,
jk_worker_t *w,
jk_ws_service_t *s)
{
return JK_FALSE;
}
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_data_t *jniWorker;
int mem_config = 0;
char *str_config = NULL;
int rc;
JNIEnv *jniEnv;
char *prefix;
if(! pThis || ! pThis->worker_private) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"In validate, assert failed - invalid parameters\n");
return JK_FALSE;
}
jniWorker = pThis->worker_private;
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);
jniWorker->tomcat_cmd_line = jk_map_getStrProp( env, props, "worker",
pThis->name,
"cmd_line", NULL );
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,
"jni.validated() Error - can't load jvm dll\n");
/* [V] no detach needed here */
return JK_FALSE;
}
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;
}
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,
"Can't find class %s\n", str_config);
/* [V] the detach here may segfault on 1.1 JVM... */
jniWorker->vm->detach(env, jniWorker->vm);
return JK_FALSE;
}
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"Loaded %s\n", jniWorker->className);
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... */
jniWorker->vm->detach(env, jniWorker->vm);
return JK_FALSE;
}
env->l->jkLog(env, env->l, JK_LOG_INFO,
"jni.validate() ok\n");
return JK_TRUE;
}
static int JK_METHOD jni_worker_init(jk_env_t *env, jk_worker_t *_this,
jk_map_t *props, jk_workerEnv_t *we)
{
jni_worker_data_t *jniWorker;
JNIEnv *jniEnv;
jstring cmd_line = NULL;
jstring stdout_name = NULL;
jstring stderr_name = NULL;
jint rc = 0;
if(! _this || ! _this->worker_private) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"In init, assert failed - invalid parameters\n");
return JK_FALSE;
}
jniWorker = _this->worker_private;
if(_this->workerEnv->vm != NULL ) {
env->l->jkLog(env, env->l, JK_LOG_DEBUG,
"jni.init(), done (been here!)\n");
return JK_TRUE;
}
if(!jniWorker->vm ||
!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;
}
env->l->jkLog(env, env->l, JK_LOG_INFO, "jni.init()\n");
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;
}
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);
_this->workerEnv->vm= jniWorker->vm;
_this->channel=env->getInstance(env, _this->pool,"channel",
"jni" );
if( _this->channel == NULL ) {
env->l->jkLog(env, env->l, JK_LOG_ERROR,
"Error creating jni channel\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_EMERG,
"Fail-> could not initialize Tomcat\n");
return JK_FALSE;
}
}
static int JK_METHOD jni_worker_destroy(jk_env_t *env, jk_worker_t *_this)
{
jni_worker_data_t *jniWorker;
JNIEnv *jniEnv;
if(!_this || ! _this->worker_private) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"In destroy, assert failed - invalid parameters\n");
return JK_FALSE;
}
jniWorker = _this->worker_private;
if(!jniWorker->vm) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"In destroy, JVM not intantiated\n");
return JK_FALSE;
}
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 = 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);
}
_this->pool->close(env, _this->pool);
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,
const char *type, const char *name)
{
jk_worker_t *_this;
jni_worker_data_t *jniData;
if(name==NULL) {
env->l->jkLog(env, env->l, JK_LOG_EMERG,
"jni.factory() NullPointerException name==null\n");
return JK_FALSE;
}
/* No singleton - you can have multiple jni workers,
running different bridges or starting different programs inprocess*/
_this=(jk_worker_t *)pool->calloc(env, pool, sizeof(jk_worker_t));
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,
"jni.factory() OutOfMemoryException \n");
return JK_FALSE;
}
_this->worker_private=jniData;
_this->pool=pool;
_this->name = _this->pool->pstrdup(env, _this->pool, name);
/* XXX split it in VM11 and VM12 util */
jk_vm_factory( env, pool, &jniData->vm, "vm", "default" );
jniData->jk_java_bridge_class = NULL;
jniData->jk_startup_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->destroy = jni_worker_destroy;
_this->service = jni_worker_service;
*result = _this;
env->l->jkLog(env, env->l, JK_LOG_INFO,
"jni.worker_factory() done\n");
return JK_TRUE;
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>