src/server/plugins/java/jvm.c

changeset 84
afd57ce39ec9
child 415
d938228c382e
equal deleted inserted replaced
83:28433f06d5ee 84:afd57ce39ec9
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 <ucx/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

mercurial