pier        01/06/25 18:37:07

  Added:       service/native java.c
  Log:
  Full UNIX service implementation checkin
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat-4.0/service/native/java.c
  
  Index: java.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",  "WebApp",  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 <[EMAIL PROTECTED]>.                        *
   *                                                                           *
   * 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/>.   *
   *                                                                           *
   * ========================================================================= */
  
  /* @version $Id: java.c,v 1.1 2001/06/26 01:37:06 pier Exp $ */
  #include "jsvc.h"
  
  #include <jni.h>
  
  static JavaVM *jvm=NULL;
  static JNIEnv *env=NULL;
  static jclass cls=NULL;
  
  #define FALSE 0
  #define TRUE !FALSE
  
  static void shutdown(JNIEnv *env, jobject source, jboolean reload) {
      log_debug("Shutdown requested (reload is %d)",reload);
      if (reload==TRUE) main_reload();
      else main_shutdown();
  }
  
  char *java_library(arg_data *args, home_data *data) {
      char *libf=NULL;
  
      /* Did we find ANY virtual machine? */
      if (data->jnum==0) {
          log_error("Cannot find any VM in Java Home %s",data->path);
          return(false);
      }
  
      /* Select the VM */
      if (args->name==NULL) {
          libf=data->jvms[0]->libr;
          log_debug("Using default JVM in %s",libf);
      } else {
          int x;
          for (x=0; x<data->jnum; x++) {
              if (data->jvms[x]->name==NULL) continue;
              if (strcmp(args->name,data->jvms[x]->name)==0) {
                  libf=data->jvms[x]->libr;
                  log_debug("Using specific JVM in %s",libf);
                  break;
              }
          }
          if (libf==NULL) {
              log_error("Invalid JVM name specified %s",args->name);
              return(NULL);
          }
      }
      return(libf);
  }
  
  /* Initialize the JVM and its environment, loading libraries and all */
  bool java_init(arg_data *args, home_data *data) {
  #ifdef OS_DARWIN
      dso_handle apph=NULL;
      char appf[1024];
  #endif /* ifdef OS_DARWIN */
      jint (*symb)(JavaVM **, JNIEnv **, JavaVMInitArgs *);
      JNINativeMethod nativemethod;
      JavaVMOption *opt=NULL;
      dso_handle libh=NULL;
      JavaVMInitArgs arg;
      char *libf=NULL;
      jint ret;
      int x;
  
      /* Decide WHAT virtual machine we need to use */
      libf=java_library(args,data);
      if (libf==NULL) {
          log_error("Cannot locate JVM library file");
          return(false);
      }
  
      /* Initialize the DSO library */
      if (dso_init()!=true) {
          log_error("Cannot initialize the dynamic library loader");
          return(false);
      }
  
      /* Load the JVM library */
      libh=dso_link(libf);
      if (libh==NULL) {
          log_error("Cannot dynamically link to %s",libf);
          return(false);
      }
      log_debug("JVM library %s loaded",libf);
  
  #ifdef OS_DARWIN
      /* MacOS/X actually has two libraries, one with the REAL vm, and one for
         the VM startup. The first one (libappshell.dyld) contains CreateVM */
      if (replace(appf,1024,"$JAVA_HOME/../Libraries/libappshell.dylib",
                   "$JAVA_HOME",data->path)!=0) {
          log_error("Cannot replace values in loader library");
          return(false);
      }
      apph=dso_link(appf);
      if (apph==NULL) {
          log_error("Cannot load required shell library %s",appf);
          return(false);
      }
      log_debug("Shell library %s loaded",appf);
  #endif /* ifdef OS_DARWIN */
      symb=dso_symbol(libh,"JNI_CreateJavaVM");
      if (symb==NULL) {
  #ifdef OS_DARWIN
          symb=dso_symbol(apph,"JNI_CreateJavaVM");
          if (symb==NULL) {
  #endif /* ifdef OS_DARWIN */
              log_error("Cannot find JVM library entry point");
              return(false);
  #ifdef OS_DARWIN
          }
  #endif /* ifdef OS_DARWIN */
      }
      log_debug("JVM library entry point found (0x%08X)",symb);
  
      /* Prepare the VM initialization arguments */
      arg.version=JNI_VERSION_1_2;
      arg.ignoreUnrecognized=FALSE;
      arg.nOptions=args->onum;
      if (arg.nOptions==0) {
          arg.options=NULL;
      } else {
          opt=(JavaVMOption *)malloc(arg.nOptions*sizeof(JavaVMOption));
          for (x=0; x<args->onum; x++) {
              opt[x].optionString=args->opts[x];
              opt[x].extraInfo=NULL;
          }
          arg.options=opt;
      }
  
      /* Do some debugging */
      if (log_debug_flag==true) {
          log_debug("+-- DUMPING JAVA VM CREATION ARGUMENTS -----------------");
          log_debug("| Version:                       %x",arg.version);
          log_debug("| Ignore Unrecognized Arguments: %s",
                    arg.ignoreUnrecognized==TRUE?"True":"False");
          log_debug("| Extra options:                 %d",arg.nOptions);
  
          for (x=0; x<args->onum; x++) {
              log_debug("|   \"%s\" (0x%08x)",opt[x].optionString,
                        opt[x].extraInfo);
          }
          log_debug("+-------------------------------------------------------");
      }
  
      /* And finally create the Java VM */
      ret=(*symb)(&jvm, &env, &arg);
      if (ret!=0) {
          log_error("Cannot create Java VM");
          return(false);
      }
      log_debug("Java VM created successfully");
  
      cls=(*env)->FindClass(env,LOADER);
      if (cls==NULL) {
          log_error("Cannot find service loader %s",LOADER);
          return(false);
      }
      log_debug("Class %s found",LOADER);
  
      nativemethod.name="shutdown";
      nativemethod.signature="(Z)V";
      nativemethod.fnPtr=shutdown;
      if((*env)->RegisterNatives(env,cls,&nativemethod,1)!=0) {
          log_error("Cannot register native methods");
          return(false);
      }
      log_debug("Native methods registered");
  
      return(true);
  }
  
  /* Destroy the Java VM */
  bool java_destroy(void) {
      if ((*jvm)->DestroyJavaVM(jvm)!=0) return(false);
      return(true);
  }
  
  /* Call the load method in our ServiceLoader class */
  bool java_load(arg_data *args) {
      jclass stringClass=NULL;
      jstring className=NULL;
      jstring currentArgument=NULL;
      jobjectArray stringArray=NULL;
      jmethodID method=NULL;
      jboolean ret=FALSE;
      int x;
  
      className=(*env)->NewStringUTF(env,args->clas);
      if (className==NULL) {
          log_error("Cannot create string for class name");
          return(false);
      }
  
      stringClass=(*env)->FindClass(env,"java/lang/String");
      if (stringClass==NULL) {
          log_error("Cannot find class java/lang/String");
          return(false);
      }
  
      stringArray=(*env)->NewObjectArray(env,args->anum,stringClass,NULL);
      if (stringArray==NULL) {
          log_error("Cannot create arguments array");
          return(false);
      }
  
      for (x=0; x<args->anum; x++) {
          currentArgument=(*env)->NewStringUTF(env,args->args[x]);
          if (currentArgument==NULL) {
              log_error("Cannot create string for argument %s",args->args[x]);
              return(false);
          }
          (*env)->SetObjectArrayElement(env,stringArray,x,currentArgument);
      }
  
      method=(*env)->GetStaticMethodID(env,cls,"load",
                          "(Ljava/lang/String;[Ljava/lang/String;)Z");
      if (method==NULL) {
          log_error("Cannot found Service Loader \"load\" entry point");
          return(false);
      }
  
      ret=(*env)->CallStaticBooleanMethod(env,cls,method,className,stringArray);
      if (ret==FALSE) {
          log_error("Cannot load service");
          return(false);
      }
  
      log_debug("Service loaded successfully");
      return(true);
  }
  
  /* Call the start method in our service loader */
  bool java_start(void) {
      jmethodID method;
      jboolean ret;
  
      method=(*env)->GetStaticMethodID(env,cls,"start","()Z");
      if (method==NULL) {
          log_error("Cannot found Service Loader \"start\" entry point");
          return(false);
      }
  
      ret=(*env)->CallStaticBooleanMethod(env,cls,method);
      if (ret==FALSE) {
          log_error("Cannot start service");
          return(false);
      }
  
      log_debug("Service started successfully");
      return(true);
  }
  
  /* Call the stop method in our service loader */
  bool java_stop(void) {
      jmethodID method;
      jboolean ret;
  
      method=(*env)->GetStaticMethodID(env,cls,"stop","()Z");
      if (method==NULL) {
          log_error("Cannot found Service Loader \"stop\" entry point");
          return(false);
      }
  
      ret=(*env)->CallStaticBooleanMethod(env,cls,method);
      if (ret==FALSE) {
          log_error("Cannot stop service");
          return(false);
      }
  
      log_debug("Service stopped successfully");
      return(true);
  }
  
  /* Call the version method in our service loader */
  bool java_version(void) {
      jmethodID method;
  
      method=(*env)->GetStaticMethodID(env,cls,"version","()V");
      if (method==NULL) {
          log_error("Cannot found Service Loader \"version\" entry point");
          return(false);
      }
  
      (*env)->CallStaticVoidMethod(env,cls,method);
      return(true);
  }
  
  /* Call the check method in our ServiceLoader class */
  bool java_check(arg_data *args) {
      jstring className=NULL;
      jmethodID method=NULL;
      jboolean ret=FALSE;
  
      log_debug("Checking service");
  
      className=(*env)->NewStringUTF(env,args->clas);
      if (className==NULL) {
          log_error("Cannot create string for class name");
          return(false);
      }
  
      method=(*env)->GetStaticMethodID(env,cls,"check","(Ljava/lang/String;)Z");
      if (method==NULL) {
          log_error("Cannot found Service Loader \"check\" entry point");
          return(false);
      }
  
      ret=(*env)->CallStaticBooleanMethod(env,cls,method,className);
      if (ret==FALSE) {
          log_error("An error was detected checking the %s service",args->clas);
          return(false);
      }
  
      log_debug("Service checked successfully");
      return(true);
  }
  
  
  
  

Reply via email to