]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
mod_java: Allow user defined java methods to be called at startup and shutdown of...
authorMichael Jerris <mike@jerris.com>
Mon, 31 May 2010 14:15:35 +0000 (10:15 -0400)
committerMichael Jerris <mike@jerris.com>
Mon, 31 May 2010 14:15:35 +0000 (10:15 -0400)
conf/autoload_configs/java.conf.xml
src/mod/languages/mod_java/modjava.c

index dadd42838715c7ff451c36bd23f7fd0e0df00bd7..3d1a3b5e5b986cbf1b912fb0578c9ad4c484e4b3 100644 (file)
@@ -8,4 +8,6 @@
     <!-- Enable remote debugging -->
     <option value="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=127.0.0.1:8000"/>
   </options>
+  <startup class="net/cog/fs/system/Control" method="startup" arg="start up arg"/>
+  <shutdown class="net/cog/fs/system/Control" method="shutdown" arg="shutdown arg"/>
 </configuration>
index 4730fa30c5483f8e586997784c32cd01f8a63bfc..98bf5f9ac831cef8eede94f266f51993779a5cda 100644 (file)
@@ -44,6 +44,21 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_java_load);
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_java_shutdown);
 SWITCH_MODULE_DEFINITION(mod_java, mod_java_load, mod_java_shutdown, NULL);
 
+struct user_method {
+       const char * class;
+       const char * method;
+       const char * arg;
+};
+
+typedef struct user_method user_method_t;
+
+struct vm_control {
+       struct user_method startup;
+       struct user_method shutdown;
+};
+
+typedef struct vm_control vm_control_t;
+static vm_control_t  vmControl;
 
 static void launch_java(switch_core_session_t *session, const char *data, JNIEnv *env)
 {
@@ -93,6 +108,67 @@ done:
         (*env)->DeleteLocalRef(env, Launcher);
 }
 
+static switch_status_t exec_user_method(user_method_t * userMethod) {
+    switch_status_t status = SWITCH_STATUS_SUCCESS;
+    jclass  class = NULL;
+    jmethodID method = NULL;
+    jstring arg = NULL;
+    JNIEnv *env;
+    jint res;
+
+    if (javaVM == NULL || userMethod->class == NULL) {
+        return status;
+    }
+
+    res = (*javaVM)->AttachCurrentThread(javaVM, (void*) &env, NULL);
+
+    if (res != JNI_OK) {
+        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error attaching thread to Java VM!\n");
+        (*env)->ExceptionDescribe(env);
+        status =  SWITCH_STATUS_FALSE;
+               goto done;
+    }
+
+    class = (*env)->FindClass(env, userMethod->class);
+
+    if (class == NULL) {
+        (*env)->ExceptionDescribe(env);
+        status =  SWITCH_STATUS_FALSE;
+        goto done;
+    }
+
+    method = (*env)->GetStaticMethodID(env, class, userMethod->method, "(Ljava/lang/String;)V");
+
+    if (method == NULL) {
+        (*env)->ExceptionDescribe(env);
+        status =  SWITCH_STATUS_FALSE;
+        goto done;
+    }
+
+    arg = (*env)->NewStringUTF(env, userMethod->arg);
+
+    if (arg == NULL) {
+        (*env)->ExceptionDescribe(env);
+        status =  SWITCH_STATUS_FALSE;
+        goto done;
+    }
+
+    (*env)->CallStaticVoidMethod(env, class, method, arg);
+
+    if ((*env)->ExceptionOccurred(env)){
+        (*env)->ExceptionDescribe(env);
+        status =  SWITCH_STATUS_FALSE;
+    }
+
+done:
+    if (arg != NULL)
+        (*env)->DeleteLocalRef(env, arg);
+    if (class != NULL)
+        (*env)->DeleteLocalRef(env, class);
+       (*javaVM)->DetachCurrentThread(javaVM);
+    return status;
+}
+
 SWITCH_STANDARD_APP(java_function)
 {
     JNIEnv *env;
@@ -111,7 +187,7 @@ SWITCH_STANDARD_APP(java_function)
         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error attaching thread to Java VM!\n");
 }
 
-static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount)
+static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount, vm_control_t * vmControl)
 {
     switch_xml_t cfg, xml;
     switch_status_t status;
@@ -121,6 +197,8 @@ static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount)
     {
         switch_xml_t javavm;
         switch_xml_t options;
+        switch_xml_t startup;
+        switch_xml_t shutdown;
 
         javavm = switch_xml_child(cfg, "javavm");
         if (javavm != NULL)
@@ -182,6 +260,25 @@ static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount)
             (*javaOptions)[i].optionString = "-Djava.library.path=" SWITCH_PREFIX_DIR SWITCH_PATH_SEPARATOR "mod";
         }
 
+       /*
+       <startup class="net/cog/fs/system/Control" method="startup" arg="start up arg"/>
+       <shutdown class="net/cog/fs/system/Control" method="shutdown" arg="shutdown arg"/>
+       */
+
+        memset(vmControl, 0, sizeof(struct vm_control));
+        startup = switch_xml_child(cfg, "startup");
+        if (startup != NULL) {
+            vmControl->startup.class = switch_xml_attr_soft(startup, "class");
+            vmControl->startup.method = switch_xml_attr_soft(startup, "method");
+            vmControl->startup.arg = switch_xml_attr_soft(startup, "arg");
+        }
+        shutdown = switch_xml_child(cfg, "shutdown");
+        if (shutdown != NULL) {
+            vmControl->shutdown.class = switch_xml_attr_soft(shutdown, "class");
+            vmControl->shutdown.method = switch_xml_attr_soft(shutdown, "method");
+            vmControl->shutdown.arg = switch_xml_attr_soft(shutdown, "arg");
+        }
+
     close:
         switch_xml_free(xml);
     }
@@ -193,7 +290,7 @@ static switch_status_t load_config(JavaVMOption **javaOptions, int *optionCount)
     return status;
 }
 
-static switch_status_t create_java_vm(JavaVMOption *options, int optionCount)
+static switch_status_t create_java_vm(JavaVMOption *options, int optionCount, vm_control_t * vmControl)
 {
     jint (JNICALL *pJNI_CreateJavaVM)(JavaVM**,void**,void*);
     switch_status_t status;
@@ -235,6 +332,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_java_load)
 {
     switch_status_t status;
     JavaVMOption *options = NULL;
+
     int optionCount = 0;
        switch_application_interface_t *app_interface;
 
@@ -249,12 +347,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_java_load)
     status = switch_core_new_memory_pool(&memoryPool);
     if (status == SWITCH_STATUS_SUCCESS)
     {
-        status = load_config(&options, &optionCount);
-        if (status == SWITCH_STATUS_SUCCESS)
-        {
-            status = create_java_vm(options, optionCount);
-            if (status == SWITCH_STATUS_SUCCESS)
-                return SWITCH_STATUS_SUCCESS;
+        status = load_config(&options, &optionCount, &vmControl);
+
+        if (status == SWITCH_STATUS_SUCCESS) {
+
+            status = create_java_vm(options, optionCount, &vmControl);
+
+            if (status == SWITCH_STATUS_SUCCESS) {
+                               status = exec_user_method(&vmControl.startup);
+                if (status == SWITCH_STATUS_SUCCESS){
+                    return SWITCH_STATUS_SUCCESS;
+                }
+                       }
+
             switch_dso_unload(javaVMHandle);
         }
         switch_core_destroy_memory_pool(&memoryPool);
@@ -270,6 +375,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_java_shutdown)
     if (javaVM == NULL)
         return SWITCH_STATUS_FALSE;
 
+    exec_user_method(&vmControl.shutdown);
     (*javaVM)->DestroyJavaVM(javaVM);
     javaVM = NULL;
     switch_dso_unload(javaVMHandle);