Add better exception handling for native code.

This commit is contained in:
md_5 2015-02-08 09:11:52 +11:00
parent eeaa44e1e7
commit b4997f6379
5 changed files with 27 additions and 17 deletions

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
CXX="g++ -nostdlib -std=c++11 -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/" CXX="g++ -std=c++11 -shared -fPIC -O3 -Wall -Werror -I$JAVA_HOME/include/ -I$JAVA_HOME/include/linux/"
$CXX src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so -lcrypto $CXX src/main/c/NativeCipherImpl.cpp -o src/main/resources/native-cipher.so -lcrypto
$CXX src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so -lz $CXX src/main/c/NativeCompressImpl.cpp -o src/main/resources/native-compress.so -lz

View File

@ -1,20 +1,9 @@
#include <string> #include <stdlib.h>
#include <zlib.h> #include <zlib.h>
#include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h" #include "net_md_5_bungee_jni_zlib_NativeCompressImpl.h"
using namespace std;
typedef unsigned char byte; typedef unsigned char byte;
jint throwException(JNIEnv *env, string message) {
jclass exClass = env->FindClass("java/lang/RuntimeException");
// Can never actually happen on a sane JVM, but better be safe anyway
if (exClass == NULL) {
return -1;
}
return env->ThrowNew(exClass, message.c_str());
}
static jfieldID consumedID; static jfieldID consumedID;
static jfieldID finishedID; static jfieldID finishedID;
@ -24,12 +13,23 @@ void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_initFields(JNIEnv
finishedID = env->GetFieldID(clazz, "finished", "Z"); finishedID = env->GetFieldID(clazz, "finished", "Z");
} }
jint throwException(JNIEnv *env, const char* message, int err) {
// These can't be static for some unknown reason
jclass exceptionClass = env->FindClass("net/md_5/bungee/jni/NativeCodeException");
jmethodID exceptionInitID = env->GetMethodID(exceptionClass, "<init>", "(Ljava/lang/String;I)V");
jstring jMessage = env->NewStringUTF(message);
jthrowable throwable = (jthrowable) env->NewObject(exceptionClass, exceptionInitID, jMessage, err);
return env->Throw(throwable);
}
void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_reset(JNIEnv* env, jobject obj, jlong ctx, jboolean compress) { void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_reset(JNIEnv* env, jobject obj, jlong ctx, jboolean compress) {
z_stream* stream = (z_stream*) ctx; z_stream* stream = (z_stream*) ctx;
int ret = (compress) ? deflateReset(stream) : inflateReset(stream); int ret = (compress) ? deflateReset(stream) : inflateReset(stream);
if (ret != Z_OK) { if (ret != Z_OK) {
throwException(env, "Could not reset z_stream: " + to_string(ret)); throwException(env, "Could not reset z_stream", ret);
} }
} }
@ -40,7 +40,7 @@ void JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_end(JNIEnv* env,
free(stream); free(stream);
if (ret != Z_OK) { if (ret != Z_OK) {
throwException(env, "Could not free z_stream: " + to_string(ret)); throwException(env, "Could not free z_stream: ", ret);
} }
} }
@ -49,7 +49,7 @@ jlong JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_init(JNIEnv* env
int ret = (compress) ? deflateInit(stream, level) : inflateInit(stream); int ret = (compress) ? deflateInit(stream, level) : inflateInit(stream);
if (ret != Z_OK) { if (ret != Z_OK) {
throwException(env, "Could not init z_stream: " + to_string(ret)); throwException(env, "Could not init z_stream", ret);
} }
return (jlong) stream; return (jlong) stream;
@ -73,7 +73,7 @@ jint JNICALL Java_net_md_15_bungee_jni_zlib_NativeCompressImpl_process(JNIEnv* e
case Z_OK: case Z_OK:
break; break;
default: default:
throwException(env, "Unknown z_stream return code: " + to_string(ret)); throwException(env, "Unknown z_stream return code", ret);
} }
env->SetIntField(obj, consumedID, inLength - stream->avail_in); env->SetIntField(obj, consumedID, inLength - stream->avail_in);

View File

@ -0,0 +1,10 @@
package net.md_5.bungee.jni;
public class NativeCodeException extends Exception
{
public NativeCodeException(String message, int reason)
{
super( message + " : " + reason );
}
}