UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2013 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <stdio.h> 30 #include <stdlib.h> 31 #include <dlfcn.h> 32 33 #include <cx/map.h> 34 35 #include "jvm.h" 36 #include "daemon/request.h" 37 38 #ifdef __i386 39 #define LIBJVM "/usr/java/jre/lib/i386/server/libjvm.so" 40 #else 41 42 #endif 43 44 static JNIEnv *env = NULL; 45 static JavaVM *jvm = NULL; 46 47 static jobject plugin_instance = NULL; 48 static jmethodID load_jmodules_method = NULL; 49 static jmethodID exec_method = NULL; 50 51 int jvm_init(pblock *pb, Session *sn, Request *rq) { 52 // load lib 53 void *lib = dlopen(LIBJVM, RTLD_GLOBAL | RTLD_NOW); 54 if(!lib) { 55 log_ereport(LOG_FAILURE, "Cannot load libjvm.so"); 56 return REQ_ABORTED; 57 } 58 59 // get symbol 60 void *sym = dlsym(lib, "JNI_CreateJavaVM"); 61 if(sym == NULL) { 62 log_ereport( 63 LOG_FAILURE, 64 "Cannot get symbol JNI_CreateJavaVM from lib"); 65 return REQ_ABORTED; 66 } 67 68 // create JVM 69 JavaVMInitArgs vm_args; 70 JavaVMOption options[2]; 71 options[0].optionString = "-Djava.class.path=lib/wsrt.jar"; 72 options[1].optionString = "-Djava.library.path=lib/"; 73 vm_args.version = JNI_VERSION_1_6; 74 vm_args.options = options; 75 vm_args.nOptions = 2; 76 vm_args.ignoreUnrecognized = JNI_TRUE; 77 78 CreateJVMFunc create_jvm = (CreateJVMFunc)sym; 79 if(create_jvm(&jvm, (void**)&env, &vm_args)) { 80 dlclose(lib); 81 log_ereport(LOG_FAILURE, "Cannot create JVM"); 82 } 83 84 // load classes and methods 85 jclass cls = (*env)->FindClass(env, "webserver/ServerPlugin"); 86 if(!cls) { 87 log_ereport( 88 LOG_FAILURE, 89 "jvm-init: missing or broken wsrt.jar"); 90 log_ereport( 91 LOG_FAILURE, 92 "jvm-init: missing class webserver.ServerPlugin"); 93 return REQ_ABORTED; 94 } 95 96 jmethodID constr = (*env)->GetMethodID(env, cls, "<init>", "()V"); 97 if(!constr) { 98 log_ereport( 99 LOG_FAILURE, 100 "jvm-init: missing or broken wsrt.jar"); 101 log_ereport( 102 LOG_FAILURE, 103 "jvm-init: missing constructor"); 104 return REQ_ABORTED; 105 } 106 plugin_instance = (*env)->NewObject(env, cls, constr); 107 if(!plugin_instance) { 108 log_ereport( 109 LOG_FAILURE, 110 "jvm-init: cannot create ServerPlugin instance"); 111 return REQ_ABORTED; 112 } 113 114 // methods 115 load_jmodules_method = (*env)->GetMethodID( 116 env, 117 cls, 118 "loadModule", 119 "(Ljava/lang/String;Ljava/lang/String;)I"); 120 if(!load_jmodules_method) { 121 log_ereport(LOG_FAILURE, "jvm-init: missing or broken wsrt.jar"); 122 log_ereport(LOG_FAILURE, "jvm-init: missing method (loadModule)"); 123 return REQ_ABORTED; 124 } 125 126 exec_method = (*env)->GetMethodID( 127 env, 128 cls, 129 "exec", 130 "(I)I"); 131 if(!exec_method) { 132 log_ereport(LOG_FAILURE, "jvm-init: missing or broken wsrt.jar"); 133 log_ereport(LOG_FAILURE, "jvm-init: missing method (exec)"); 134 return REQ_ABORTED; 135 } 136 137 138 return REQ_PROCEED; 139 } 140 141 int load_jmodules(pblock *pb, Session *sn, Request *rq) { 142 char *jar = pblock_findval("jar", pb); 143 char *classes = pblock_findval("classes", pb); 144 145 if(!jar || !classes) { 146 log_ereport( 147 LOG_MISCONFIG, 148 "load-jmodule: missing parameters (jar, classes)"); 149 return REQ_ABORTED; 150 } 151 152 // check jvm 153 if(!plugin_instance) { 154 log_ereport( 155 LOG_FAILURE, 156 "load-jmodules: java plugin not properly loaded"); 157 return REQ_ABORTED; 158 } 159 if(!load_jmodules_method) { 160 log_ereport( 161 LOG_FAILURE, 162 "load-jmodules: java plugin not properly loaded"); 163 return REQ_ABORTED; 164 } 165 166 // load java module 167 jstring jar_param = (*env)->NewStringUTF(env, jar); 168 jstring classes_param = (*env)->NewStringUTF(env, classes); 169 170 jint ret = (*env)->CallIntMethod( 171 env, 172 plugin_instance, 173 load_jmodules_method, 174 jar_param, 175 classes_param); 176 177 // free stuff 178 (*env)->DeleteLocalRef(env, jar_param); 179 (*env)->DeleteLocalRef(env, classes_param); 180 181 return ret; 182 } 183 184 int jexec(pblock *pb, Session *sn, Request *rq) { 185 return REQ_NOACTION; 186 } 187 188 int jvm_method_exec(FuncStruct *func, pblock *pb, Session *sn, Request *rq) { 189 printf("jvm_method_exec: %d\n", func); 190 NSAPIRequest *nrq = (NSAPIRequest*)rq; 191 192 JNIEnv *e = NULL; 193 int r = (*jvm)->AttachCurrentThread(jvm, (void**)&e, NULL); 194 195 jint index = (jint)func->exec_data; 196 printf("(C) exec: %d\n", index); 197 198 jint ret = (*env)->CallIntMethod( 199 env, 200 plugin_instance, 201 exec_method, 202 index); 203 204 return ret; 205 } 206 207