1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
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
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
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
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
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
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
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
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