static jint initializeJavaVM(JVMOptList *optList) { jint jstat; JavaVMInitArgs vm_args; if(pljava_debug) { elog(INFO, "Backend pid = %d. Attach the debugger and set pljava_debug to false to continue", getpid()); while(pljava_debug) pg_usleep(1000000L); } vm_args.nOptions = optList->size; vm_args.options = optList->options; vm_args.version = JNI_VERSION_1_4; vm_args.ignoreUnrecognized = JNI_FALSE; elog(DEBUG2, "creating Java virtual machine"); jstat = JNI_createVM(&s_javaVM, &vm_args); if(jstat == JNI_OK && JNI_exceptionCheck()) { JNI_exceptionDescribe(); JNI_exceptionClear(); jstat = JNI_ERR; } JVMOptList_delete(optList); return jstat; }
/** * Initialize the session */ static void initJavaSession(void) { jclass sessionClass = PgObject_getJavaClass("org/postgresql/pljava/internal/Session"); jmethodID init = PgObject_getStaticJavaMethod(sessionClass, "init", "()J"); mainThreadId = JNI_callStaticLongMethod(sessionClass, init); JNI_deleteLocalRef(sessionClass); if(JNI_exceptionCheck()) { JNI_exceptionDescribe(); JNI_exceptionClear(); ereport(ERROR, ( errcode(ERRCODE_INTERNAL_ERROR), errmsg("Unable to initialize java session"))); } }
/** * Initialize security */ void Backend_setJavaSecurity(bool trusted) { if(trusted != s_currentTrust) { /* GCJ has major issues here. Real work on SecurityManager and * related classes has just started in version 4.0.0. */ #ifndef GCJ JNI_callStaticVoidMethod(s_Backend_class, s_setTrusted, (jboolean)trusted); if(JNI_exceptionCheck()) { JNI_exceptionDescribe(); JNI_exceptionClear(); ereport(ERROR, ( errcode(ERRCODE_INTERNAL_ERROR), errmsg("Unable to initialize java security"))); } #endif s_currentTrust = trusted; } }
static void Function_init(Function self, ParseResult info, Form_pg_proc procStruct, PG_FUNCTION_ARGS) { StringInfoData sign; jobject loader; jstring className; /* Get the ClassLoader for the schema that this function belongs to */ jstring schemaName = getSchemaName(procStruct->pronamespace); /* Install the type map for the current schema. This must be done ASAP since * many other functions (including obtaining the loader) depends on it. */ jobject tmp = JNI_callStaticObjectMethod(s_Loader_class, s_Loader_getTypeMap, schemaName); self->func.nonudt.typeMap = JNI_newGlobalRef(tmp); JNI_deleteLocalRef(tmp); self->readOnly = (procStruct->provolatile != PROVOLATILE_VOLATILE); self->isUDT = info->isUDT; currentInvocation->function = self; /* Get the ClassLoader for the schema that this function belongs to */ loader = JNI_callStaticObjectMethod(s_Loader_class, s_Loader_getSchemaLoader, schemaName); JNI_deleteLocalRef(schemaName); elog(DEBUG1, "Loading class %s", info->className); className = String_createJavaStringFromNTS(info->className); tmp = JNI_callObjectMethod(loader, s_ClassLoader_loadClass, className); JNI_deleteLocalRef(loader); JNI_deleteLocalRef(className); self->clazz = (jclass)JNI_newGlobalRef(tmp); JNI_deleteLocalRef(tmp); if(self->isUDT) { setupUDT(self, info, procStruct); return; } if(CALLED_AS_TRIGGER(fcinfo)) { self->func.nonudt.typeMap = 0; setupTriggerParams(self, info); } else { setupFunctionParams(self, info, procStruct, fcinfo); } initStringInfo(&sign); buildSignature(self, &sign, self->func.nonudt.returnType, false); elog(DEBUG1, "Obtaining method %s.%s %s", info->className, info->methodName, sign.data); self->func.nonudt.method = JNI_getStaticMethodIDOrNull(self->clazz, info->methodName, sign.data); if(self->func.nonudt.method == 0) { char* origSign = sign.data; Type altType = 0; Type realRetType = self->func.nonudt.returnType; elog(DEBUG1, "Method %s.%s %s not found", info->className, info->methodName, origSign); if(Type_isPrimitive(self->func.nonudt.returnType)) { /* * One valid reason for not finding the method is when * the return type used in the signature is a primitive and * the true return type of the method is the object class that * corresponds to that primitive. */ altType = Type_getObjectType(self->func.nonudt.returnType); realRetType = altType; } else if(strcmp(Type_getJavaTypeName(self->func.nonudt.returnType), "java.sql.ResultSet") == 0) { /* * Another reason might be that we expected a ResultSetProvider * but the implementation returns a ResultSetHandle that needs to be * wrapped. The wrapping is internal so we retain the original * return type anyway. */ altType = realRetType; } if(altType != 0) { JNI_exceptionClear(); initStringInfo(&sign); buildSignature(self, &sign, altType, true); elog(DEBUG1, "Obtaining method %s.%s %s", info->className, info->methodName, sign.data); self->func.nonudt.method = JNI_getStaticMethodIDOrNull(self->clazz, info->methodName, sign.data); if(self->func.nonudt.method != 0) self->func.nonudt.returnType = realRetType; } if(self->func.nonudt.method == 0) PgObject_throwMemberError(self->clazz, info->methodName, origSign, true, true); if(sign.data != origSign) pfree(origSign); } pfree(sign.data); }