1 2 /* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6 #include <nxt_auto_config.h> 7 8 #include <nxt_unit.h> 9 #include <jni.h> 10 11 #include "nxt_jni.h" 12 #include "nxt_jni_Context.h" 13 #include "nxt_jni_URLClassLoader.h" 14 15 16 static jclass nxt_java_Context_class; 17 static jmethodID nxt_java_Context_start; 18 static jmethodID nxt_java_Context_service; 19 static jmethodID nxt_java_Context_stop; 20 21 static void JNICALL nxt_java_Context_log(JNIEnv *env, jclass cls, 22 jlong ctx_ptr, jstring msg, jint msg_len); 23 static void JNICALL nxt_java_Context_trace(JNIEnv *env, jclass cls, 24 jlong ctx_ptr, jstring msg, jint msg_len); 25 26 27 int 28 nxt_java_initContext(JNIEnv *env, jobject cl) 29 { 30 int res; 31 jclass cls; 32 33 cls = nxt_java_loadClass(env, cl, "nginx.unit.Context"); 34 if (cls == NULL) { 35 nxt_unit_warn(NULL, "nginx.unit.Context not found"); 36 return NXT_UNIT_ERROR; 37 } 38 39 nxt_java_Context_class = (*env)->NewGlobalRef(env, cls); 40 (*env)->DeleteLocalRef(env, cls); 41 cls = nxt_java_Context_class; 42 43 nxt_java_Context_start = (*env)->GetStaticMethodID(env, cls, "start", 44 "(Ljava/lang/String;[Ljava/net/URL;)Lnginx/unit/Context;"); 45 if (nxt_java_Context_start == NULL) { 46 nxt_unit_warn(NULL, "nginx.unit.Context.start() not found"); 47 goto failed; 48 } 49 50 nxt_java_Context_service = (*env)->GetMethodID(env, cls, "service", 51 "(Lnginx/unit/Request;Lnginx/unit/Response;)V"); 52 if (nxt_java_Context_service == NULL) { 53 nxt_unit_warn(NULL, "nginx.unit.Context.service() not found"); 54 goto failed; 55 } 56 57 nxt_java_Context_stop = (*env)->GetMethodID(env, cls, "stop", "()V"); 58 if (nxt_java_Context_service == NULL) { 59 nxt_unit_warn(NULL, "nginx.unit.Context.stop() not found"); 60 goto failed; 61 } 62 63 JNINativeMethod context_methods[] = { 64 { (char *) "log", 65 (char *) "(JLjava/lang/String;I)V", 66 nxt_java_Context_log }, 67 68 { (char *) "trace", 69 (char *) "(JLjava/lang/String;I)V", 70 nxt_java_Context_trace }, 71 72 }; 73 74 res = (*env)->RegisterNatives(env, nxt_java_Context_class, 75 context_methods, 76 sizeof(context_methods) 77 / sizeof(context_methods[0])); 78 79 nxt_unit_debug(NULL, "registered Context methods: %d", res); 80 81 if (res != 0) { 82 nxt_unit_warn(NULL, "registering natives for Context failed"); 83 goto failed; 84 } 85 86 return NXT_UNIT_OK; 87 88 failed: 89 90 (*env)->DeleteGlobalRef(env, cls); 91 return NXT_UNIT_ERROR; 92 } 93 94 95 jobject 96 nxt_java_startContext(JNIEnv *env, const char *webapp, jobject classpaths) 97 { 98 jstring webapp_str; 99 100 webapp_str = (*env)->NewStringUTF(env, webapp); 101 if (webapp_str == NULL) { 102 return NULL; 103 } 104 105 return (*env)->CallStaticObjectMethod(env, nxt_java_Context_class, 106 nxt_java_Context_start, webapp_str, 107 classpaths); 108 } 109 110 111 void 112 nxt_java_service(JNIEnv *env, jobject ctx, jobject jreq, jobject jresp) 113 { 114 (*env)->CallVoidMethod(env, ctx, nxt_java_Context_service, jreq, jresp); 115 } 116 117 118 void 119 nxt_java_stopContext(JNIEnv *env, jobject ctx) 120 { 121 (*env)->CallVoidMethod(env, ctx, nxt_java_Context_stop); 122 } 123 124 125 static void JNICALL 126 nxt_java_Context_log(JNIEnv *env, jclass cls, jlong ctx_ptr, jstring msg, 127 jint msg_len) 128 { 129 const char *msg_str; 130 nxt_unit_ctx_t *ctx; 131 132 ctx = nxt_jlong2ptr(ctx_ptr); 133 134 msg_str = (*env)->GetStringUTFChars(env, msg, NULL); 135 if (msg_str == NULL) { 136 return; 137 } 138 139 nxt_unit_log(ctx, NXT_UNIT_LOG_INFO, "%.*s", msg_len, msg_str); 140 141 (*env)->ReleaseStringUTFChars(env, msg, msg_str); 142 } 143 144 145 static void JNICALL 146 nxt_java_Context_trace(JNIEnv *env, jclass cls, jlong ctx_ptr, jstring msg, 147 jint msg_len) 148 { 149 #if (NXT_DEBUG) 150 const char *msg_str; 151 nxt_unit_ctx_t *ctx; 152 153 ctx = nxt_jlong2ptr(ctx_ptr); 154 155 msg_str = (*env)->GetStringUTFChars(env, msg, NULL); 156 if (msg_str == NULL) { 157 return; 158 } 159 160 nxt_unit_debug(ctx, "%.*s", msg_len, msg_str); 161 162 (*env)->ReleaseStringUTFChars(env, msg, msg_str); 163 #endif 164 } 165