jint netty_unix_filedescriptor_JNI_OnLoad(JNIEnv* env, const char* nettyPackagePrefix) { void* mem = malloc(1); if (mem == NULL) { netty_unix_errors_throwOutOfMemoryError(env); return JNI_ERR; } jobject directBuffer = (*env)->NewDirectByteBuffer(env, mem, 1); if (directBuffer == NULL) { free(mem); netty_unix_errors_throwOutOfMemoryError(env); return JNI_ERR; } if ((*env)->GetDirectBufferAddress(env, directBuffer) == NULL) { free(mem); netty_unix_errors_throwRuntimeException(env, "failed to get direct buffer address"); return JNI_ERR; } jclass cls = (*env)->GetObjectClass(env, directBuffer); // Get the method id for Buffer.position() and Buffer.limit(). These are used as fallback if // it is not possible to obtain the position and limit using the fields directly. posId = (*env)->GetMethodID(env, cls, "position", "()I"); if (posId == NULL) { free(mem); // position method was not found.. something is wrong so bail out netty_unix_errors_throwRuntimeException(env, "failed to get method ID: ByteBuffer.position()"); return JNI_ERR; } limitId = (*env)->GetMethodID(env, cls, "limit", "()I"); if (limitId == NULL) { free(mem); // limit method was not found.. something is wrong so bail out netty_unix_errors_throwRuntimeException(env, "failed to get method ID: ByteBuffer.limit()"); return JNI_ERR; } // Try to get the ids of the position and limit fields. We later then check if we was able // to find them and if so use them get the position and limit of the buffer. This is // much faster then call back into java via (*env)->CallIntMethod(...). posFieldId = (*env)->GetFieldID(env, cls, "position", "I"); if (posFieldId == NULL) { // this is ok as we can still use the method so just clear the exception (*env)->ExceptionClear(env); } limitFieldId = (*env)->GetFieldID(env, cls, "limit", "I"); if (limitFieldId == NULL) { // this is ok as we can still use the method so just clear the exception (*env)->ExceptionClear(env); } free(mem); }
jint netty_kqueue_bsdsocket_JNI_OnLoad(JNIEnv* env, const char* packagePrefix) { // Register the methods which are not referenced by static member variables JNINativeMethod* dynamicMethods = createDynamicMethodsTable(packagePrefix); if (netty_unix_util_register_natives(env, packagePrefix, "io/netty/channel/kqueue/BsdSocket", dynamicMethods, dynamicMethodsTableSize()) != 0) { freeDynamicMethodsTable(dynamicMethods); return JNI_ERR; } freeDynamicMethodsTable(dynamicMethods); dynamicMethods = NULL; // Initialize this module char* nettyClassName = netty_unix_util_prepend(packagePrefix, "io/netty/channel/DefaultFileRegion"); jclass fileRegionCls = (*env)->FindClass(env, nettyClassName); free(nettyClassName); nettyClassName = NULL; if (fileRegionCls == NULL) { return JNI_ERR; } fileChannelFieldId = (*env)->GetFieldID(env, fileRegionCls, "file", "Ljava/nio/channels/FileChannel;"); if (fileChannelFieldId == NULL) { netty_unix_errors_throwRuntimeException(env, "failed to get field ID: DefaultFileRegion.file"); return JNI_ERR; } transferredFieldId = (*env)->GetFieldID(env, fileRegionCls, "transferred", "J"); if (transferredFieldId == NULL) { netty_unix_errors_throwRuntimeException(env, "failed to get field ID: DefaultFileRegion.transferred"); return JNI_ERR; } jclass fileChannelCls = (*env)->FindClass(env, "sun/nio/ch/FileChannelImpl"); if (fileChannelCls == NULL) { // pending exception... return JNI_ERR; } fileDescriptorFieldId = (*env)->GetFieldID(env, fileChannelCls, "fd", "Ljava/io/FileDescriptor;"); if (fileDescriptorFieldId == NULL) { netty_unix_errors_throwRuntimeException(env, "failed to get field ID: FileChannelImpl.fd"); return JNI_ERR; } jclass fileDescriptorCls = (*env)->FindClass(env, "java/io/FileDescriptor"); if (fileDescriptorCls == NULL) { // pending exception... return JNI_ERR; } fdFieldId = (*env)->GetFieldID(env, fileDescriptorCls, "fd", "I"); if (fdFieldId == NULL) { netty_unix_errors_throwRuntimeException(env, "failed to get field ID: FileDescriptor.fd"); return JNI_ERR; } stringCls = (*env)->FindClass(env, "java/lang/String"); if (stringCls == NULL) { // pending exception... return JNI_ERR; } nettyClassName = netty_unix_util_prepend(packagePrefix, "io/netty/channel/unix/PeerCredentials"); jclass localPeerCredsClass = (*env)->FindClass(env, nettyClassName); free(nettyClassName); nettyClassName = NULL; if (localPeerCredsClass == NULL) { // pending exception... return JNI_ERR; } peerCredentialsClass = (jclass) (*env)->NewGlobalRef(env, localPeerCredsClass); if (peerCredentialsClass == NULL) { // out-of-memory! netty_unix_errors_throwOutOfMemoryError(env); return JNI_ERR; } peerCredentialsMethodId = (*env)->GetMethodID(env, peerCredentialsClass, "<init>", "(II[I)V"); if (peerCredentialsMethodId == NULL) { netty_unix_errors_throwRuntimeException(env, "failed to get method ID: PeerCredentials.<init>(int, int, int[])"); return JNI_ERR; } return NETTY_JNI_VERSION; }