diff --git a/jni.cabal b/jni.cabal
--- a/jni.cabal
+++ b/jni.cabal
@@ -1,5 +1,5 @@
 name:                jni
-version:             0.4.0
+version:             0.5.0
 synopsis:            Complete JNI raw bindings.
 description:         Please see README.md.
 homepage:            https://github.com/tweag/inline-java/tree/master/jni#readme
@@ -38,8 +38,7 @@
     containers >=0.5,
     constraints >=0.8,
     deepseq >= 1.4.2,
-    singletons >= 2.0,
-    thread-local-storage >=0.1
+    singletons >= 2.0
   if impl(ghc < 8.2.1)
     build-depends:
       inline-c >=0.5.6.1
diff --git a/src/Foreign/JNI.c b/src/Foreign/JNI.c
--- a/src/Foreign/JNI.c
+++ b/src/Foreign/JNI.c
@@ -1,712 +0,0 @@
-
-#include <jni.h>
-
-#include <stdio.h>
-
-#include <errno.h>
-
-#include <stdlib.h>
-
-jthrowable inline_c_Foreign_JNI_0_547acbc2ed14c804f8e5133e90bd68e8a83f9c40(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {
-return ( (*env_inline_c_0)->ExceptionOccurred(env_inline_c_1) );
-}
-
-
-void inline_c_Foreign_JNI_1_78814a28f200ba50ae6a800d1c57dc6512afa523(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {
- (*env_inline_c_0)->ExceptionDescribe(env_inline_c_1) ;
-}
-
-
-void inline_c_Foreign_JNI_2_fa3d0bf0766f27928a66a4776f60d76979f8c97d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1) {
- (*env_inline_c_0)->ExceptionClear(env_inline_c_1) ;
-}
-
-
-JNIEnv * inline_c_Foreign_JNI_3_7a31865bf33245c9e432165e1fe1577264708e3b() {
-
-      jsize num_jvms;
-      JavaVM *jvm;
-                                                                              
-                                                     
-      JNI_GetCreatedJavaVMs(&jvm, 1, &num_jvms);
-      JNIEnv *env;
-
-      if(!num_jvms) {
-              fprintf(stderr, "No JVM has been initialized yet.\n");
-              exit(EFAULT);
-      }
-
-                                                                               
-                  
-         
-      (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void**)&env, NULL);
-      return env; 
-}
-
-
-JavaVM * inline_c_Foreign_JNI_4_fecb5a47df7d5ce6c5789c5d9c5b02f94a0f7058(int n_inline_c_0, int n_inline_c_1, char ** coptions_inline_c_2, int n_inline_c_3) {
-
-          JavaVM *jvm;
-          JNIEnv *env;
-          JavaVMInitArgs vm_args;
-          JavaVMOption *options = malloc(sizeof(JavaVMOption) * n_inline_c_0);
-          for(int i = 0; i < n_inline_c_1; i++)
-                  options[i].optionString = coptions_inline_c_2[i];
-          vm_args.version = JNI_VERSION_1_6;
-          vm_args.nOptions = n_inline_c_3;
-          vm_args.options = options;
-          vm_args.ignoreUnrecognized = 0;
-          JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
-          free(options);
-          return jvm; 
-}
-
-
-void inline_c_Foreign_JNI_5_b584a6aa1eb7dfd9c78995e2ecba0ce2c820e741(JavaVM * jvm_inline_c_0, JavaVM * jvm_inline_c_1) {
- (*jvm_inline_c_0)->DestroyJavaVM(jvm_inline_c_1); 
-}
-
-
-jclass inline_c_Foreign_JNI_6_8c440e181516a3630ffa1c69f19cdd49c5ea5146(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, char * namep_inline_c_2, jobject loader_inline_c_3, char * buf_inline_c_4, long buf_inline_c_5) {
-return (
-      (*env_inline_c_0)->DefineClass(env_inline_c_1,
-                                     namep_inline_c_2,
-                                     loader_inline_c_3,
-                                     buf_inline_c_4,
-                                     buf_inline_c_5) );
-}
-
-
-jint inline_c_Foreign_JNI_7_b2b4b4a025c54c183ac34fda20ed77aaa1cbd6ed(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, JNINativeMethod * cmethods_inline_c_3, int numMethods_inline_c_4) {
-return (
-             (*env_inline_c_0)->RegisterNatives(env_inline_c_1,
-                                                cls_inline_c_2,
-                                                cmethods_inline_c_3,
-                                                numMethods_inline_c_4) );
-}
-
-
-jint inline_c_Foreign_JNI_8_7da57142503fa6323136b7c159710e69a3507ecd(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-       (*env_inline_c_0)->Throw(env_inline_c_1,
-                                obj_inline_c_2) );
-}
-
-
-jint inline_c_Foreign_JNI_9_28bfcee12881af1c4a1c7de9b19c8263659c32d9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * msgp_inline_c_3) {
-return (
-       (*env_inline_c_0)->ThrowNew(env_inline_c_1,
-                                   cls_inline_c_2,
-                                   msgp_inline_c_3) );
-}
-
-
-jclass inline_c_Foreign_JNI_10_98f2efdfb85a70a64012d4a321b2e1b53ec6d783(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, char * namep_inline_c_2) {
-return ( (*env_inline_c_0)->FindClass(env_inline_c_1, namep_inline_c_2) );
-}
-
-
-jobject inline_c_Foreign_JNI_11_db79f2d25dd672f2593a68b078850f23bf59b54d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID constr_inline_c_3, jvalue * cargs_inline_c_4) {
-return (
-        (*env_inline_c_0)->NewObjectA(env_inline_c_1,
-                                      cls_inline_c_2,
-                                      constr_inline_c_3,
-                                      cargs_inline_c_4) );
-}
-
-
-jfieldID inline_c_Foreign_JNI_12_24f9a5b843f700dd367457745083b0f737727165(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * fieldnamep_inline_c_3, char * sigp_inline_c_4) {
-return (
-      (*env_inline_c_0)->GetFieldID(env_inline_c_1,
-                                    cls_inline_c_2,
-                                    fieldnamep_inline_c_3,
-                                    sigp_inline_c_4) );
-}
-
-
-jfieldID inline_c_Foreign_JNI_13_7f51c9e3dfc10d19fa55f2bad6ee5d30c55df36e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * fieldnamep_inline_c_3, char * sigp_inline_c_4) {
-return (
-      (*env_inline_c_0)->GetStaticFieldID(env_inline_c_1,
-                                          cls_inline_c_2,
-                                          fieldnamep_inline_c_3,
-                                          sigp_inline_c_4) );
-}
-
-
-jobject inline_c_Foreign_JNI_14_d3bbd4f49ae66a171a74a554b1ad29de1e653fbe(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetObjectField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jboolean inline_c_Foreign_JNI_15_a6c318bded4eb76e31688bb79797fe16d6ad53cd(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetBooleanField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jbyte inline_c_Foreign_JNI_16_ce49e2a35bd9168e5441c414c23484ab5ed3bfd1(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetByteField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jchar inline_c_Foreign_JNI_17_c943f6f26c7dc18be8ee2dbae90e076a32d0bc7b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetCharField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jshort inline_c_Foreign_JNI_18_4f9206f7afb17d7f7a4ca9c25e5e6ed84e09389c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetShortField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jint inline_c_Foreign_JNI_19_0163f5dc997937b24f9a57dbb7fac4a42db7f087(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetIntField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jlong inline_c_Foreign_JNI_20_46309075736c07065202cd83573f912c5501b005(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetLongField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jfloat inline_c_Foreign_JNI_21_2c66977fbc363fd8fb05ce6ab75fd556531d5a17(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetFloatField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jdouble inline_c_Foreign_JNI_22_272ef095b5f25c1f0f9482e390b6a782adff8c47(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetDoubleField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3) );
-}
-
-
-jobject inline_c_Foreign_JNI_23_5c71747967eb4276bca3e20b379750babbebda8e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticObjectField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jboolean inline_c_Foreign_JNI_24_b176fa5abc4a517382107db7f9cf6e9d39f42790(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticBooleanField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jbyte inline_c_Foreign_JNI_25_27a626282a93b144decfac0d91b1620bd593f9b3(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticByteField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jchar inline_c_Foreign_JNI_26_a04d9bdb806b0e16000ef35f7159e5dd16b3dd70(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticCharField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jshort inline_c_Foreign_JNI_27_5bbf8ff1a31ec47edf1a6f51423acec6a8c165d9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticShortField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jint inline_c_Foreign_JNI_28_e412724b75f372f7be355611dc8047fb9ae1126b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticIntField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jlong inline_c_Foreign_JNI_29_89d32b3c2be6d4e4e01285d42a1845567da8d5ef(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticLongField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jfloat inline_c_Foreign_JNI_30_fb5c2b1d3de9b233f712bd7c5d5e38deb356b1e9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticFloatField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-jdouble inline_c_Foreign_JNI_31_492512f55c5b7ee515200d9a8a08009e7788aa22(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3) {
-return (       (*env_inline_c_0)->GetStaticDoubleField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3) );
-}
-
-
-void inline_c_Foreign_JNI_32_584abfc1ea057f29617db577aa8a7bcf87c50277(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jobject x_inline_c_4) {
-       (*env_inline_c_0)->SetObjectField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_33_d740752f4e956bdbcfdeb49ad9c4daac79454740(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jboolean x_inline_c_4) {
-       (*env_inline_c_0)->SetBooleanField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_34_7c7e899dc92453c6973878ad7b630dca1101ec2f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jbyte x_inline_c_4) {
-       (*env_inline_c_0)->SetByteField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_35_77351519d67b4f4ab49c6b1dc32a190a8f7a2524(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jchar x_inline_c_4) {
-       (*env_inline_c_0)->SetCharField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_36_cbc8c11ddfd08b4a88953c743e6ea91feb0ac607(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jshort x_inline_c_4) {
-       (*env_inline_c_0)->SetShortField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_37_f318d1d52db33d7bf0dc7e5c6e9e0a71484ecb5d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jint x_inline_c_4) {
-       (*env_inline_c_0)->SetIntField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_38_0d005c04266d114f3826b408c1b80edae3cd0fe9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jlong x_inline_c_4) {
-       (*env_inline_c_0)->SetLongField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_39_6a8a9ce4e7e8acae90231495db2fd8854b488d5d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jfloat x_inline_c_4) {
-       (*env_inline_c_0)->SetFloatField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_40_c3947546832da8a398f347c27908ee58b78f6b9d(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jfieldID field_inline_c_3, jdouble x_inline_c_4) {
-       (*env_inline_c_0)->SetDoubleField(env_inline_c_1,                                               obj_inline_c_2,                                               field_inline_c_3,                                               x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_41_b84acff3f2e26a2a2d4e3f2a7fa46cdfbc099912(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jobject x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticObjectField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_42_a02725e5169b86b9c1c527aaf96872a055940707(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jboolean x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticBooleanField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_43_a3232ebc0e49f3217ef3dd1bce52bbb83462aede(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jbyte x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticByteField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_44_6e323e9e26073d2c2b53ede3444cdf73ce5b4aad(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jchar x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticCharField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_45_f6cfa9b49f03261d0c67c68fb9595a818e3e28cb(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jshort x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticShortField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_46_f382d7603879ddb1eca55b052c49ed4b418e2cc7(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jint x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticIntField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_47_02c96789057bffbad5c0921c8e94f8ffc7f6a392(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jlong x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticLongField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_48_2f1ae23c6909cb66e439ed94bb49a5b5b117268c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jfloat x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticFloatField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-void inline_c_Foreign_JNI_49_3f17c8ae6483640141674f2ae41409e830a60690(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass klass_inline_c_2, jfieldID field_inline_c_3, jdouble x_inline_c_4) {
-       (*env_inline_c_0)->SetStaticDoubleField(env_inline_c_1,                                                     klass_inline_c_2,                                                     field_inline_c_3,                                                     x_inline_c_4); 
-}
-
-
-jmethodID inline_c_Foreign_JNI_50_e722a7a0d6891db8a6cda0ec21cc6312aaeec3c0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * methodnamep_inline_c_3, char * sigp_inline_c_4) {
-return (
-      (*env_inline_c_0)->GetMethodID(env_inline_c_1,
-                                     cls_inline_c_2,
-                                     methodnamep_inline_c_3,
-                                     sigp_inline_c_4) );
-}
-
-
-jmethodID inline_c_Foreign_JNI_51_196e9055f6891bfa3cf856c108612c9572ecc877(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, char * methodnamep_inline_c_3, char * sigp_inline_c_4) {
-return (
-      (*env_inline_c_0)->GetStaticMethodID(env_inline_c_1,
-                                           cls_inline_c_2,
-                                           methodnamep_inline_c_3,
-                                           sigp_inline_c_4) );
-}
-
-
-jclass inline_c_Foreign_JNI_52_9f847198f949d76076adbd2e63e17b2ed0e73c41(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-      (*env_inline_c_0)->GetObjectClass(env_inline_c_1,
-                                        obj_inline_c_2) );
-}
-
-
-jobject inline_c_Foreign_JNI_53_16595ba5c6f78926bf8bd31d9d0e8bf072131bb0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-        (*env_inline_c_0)->NewGlobalRef(env_inline_c_1,
-                                        obj_inline_c_2) );
-}
-
-
-jobject inline_c_Foreign_JNI_54_16595ba5c6f78926bf8bd31d9d0e8bf072131bb0(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-        (*env_inline_c_0)->NewGlobalRef(env_inline_c_1,
-                                        obj_inline_c_2) );
-}
-
-
-void inline_c_Foreign_JNI_55_f542a39c35a9eb0c083a4e59c4f21de5ad94e141(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
- (*env_inline_c_0)->DeleteGlobalRef(env_inline_c_1
-                                                            ,obj_inline_c_2);
-                        
-}
-
-
-jobject inline_c_Foreign_JNI_56_286b821e24496c30618bcd36d10e07939424a96e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-      (*env_inline_c_0)->NewLocalRef(env_inline_c_1,
-                                     obj_inline_c_2) );
-}
-
-
-void inline_c_Foreign_JNI_57_f46c3362caa2b895c87351e1914a06c012eee294(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-
-      (*env_inline_c_0)->DeleteLocalRef(env_inline_c_1,
-                                        obj_inline_c_2) ;
-}
-
-
-jint inline_c_Foreign_JNI_58_c49bfdb1320e2f77592a15068a422089ae09feba(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jint capacity_inline_c_2) {
-
-      (*env_inline_c_0)->PushLocalFrame(env_inline_c_1,
-                                        capacity_inline_c_2); 
-}
-
-
-jobject inline_c_Foreign_JNI_59_53148f1b21d55375d63ea7ade9238bc4f16e149e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2) {
-return (
-      (*env_inline_c_0)->PopLocalFrame(env_inline_c_1,
-                                       obj_inline_c_2) );
-}
-
-
-void inline_c_Foreign_JNI_60_8d66436d754c77c4f92234fe2c72cb9e8a9ad940(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-       (*env_inline_c_0)->CallVoidMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) ;
-}
-
-
-jobject inline_c_Foreign_JNI_61_15d6a4ae1fac1a6ba84db740b2bfac9d44b23329(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallObjectMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jboolean inline_c_Foreign_JNI_62_71e1f15d31cfe83371d148dbf20d2aebf0293c53(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallBooleanMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jbyte inline_c_Foreign_JNI_63_5c031f42ce827bc7ef3320331f4333dfb7ddaa3a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallByteMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jchar inline_c_Foreign_JNI_64_f67cb9064f7392b8f942ac21b300b8594ddc8043(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallCharMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jshort inline_c_Foreign_JNI_65_3dc48e937e27459da9000a1fba7694c91562fbd6(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallShortMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jint inline_c_Foreign_JNI_66_0d9906f84552f67ba8fc08d4403ca6919417f4de(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallIntMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jlong inline_c_Foreign_JNI_67_ff3b913f1c1e13665522e2fa9f46cf345cef625e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallLongMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jfloat inline_c_Foreign_JNI_68_7d9a7c851ecb7d144f8aadac5cb17df79f87edfc(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallFloatMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-jdouble inline_c_Foreign_JNI_69_9928358856d291d7c670b6bb00810c66255dcc65(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject obj_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallDoubleMethodA(env_inline_c_1,                                                  obj_inline_c_2,                                                  method_inline_c_3,                                                  cargs_inline_c_4) );
-}
-
-
-void inline_c_Foreign_JNI_70_5e76a5cd24826d8a13100c53ae77823083465978(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-       (*env_inline_c_0)->CallStaticVoidMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) ;
-}
-
-
-jobject inline_c_Foreign_JNI_71_6b65c20aae594d93c02434b3de002e443794ad14(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticObjectMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jboolean inline_c_Foreign_JNI_72_58bcbcce6c8bf92799bd1db44c288a7b0a260a36(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticBooleanMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jbyte inline_c_Foreign_JNI_73_1f0c41a419f29557514552df4d07022a006f2ca3(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticByteMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jchar inline_c_Foreign_JNI_74_51a3cb1cefc6391ba5958a887d84196690a418f2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticCharMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jshort inline_c_Foreign_JNI_75_5822dfce2b301e3b90f80885a4a5838bdc57cd44(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticShortMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jint inline_c_Foreign_JNI_76_4fdc28424fe7ef156763f715ef79463ed387abb2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticIntMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jlong inline_c_Foreign_JNI_77_93382b358dc7f0275c6a620eaa67fdfd75167d54(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticLongMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jfloat inline_c_Foreign_JNI_78_89ea2435847f3d94e8b71bcceba739a077829ca9(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticFloatMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jdouble inline_c_Foreign_JNI_79_0b9bb41f21f19495338507ff5779f50a17ac0245(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jclass cls_inline_c_2, jmethodID method_inline_c_3, jvalue * cargs_inline_c_4) {
-return (       (*env_inline_c_0)->CallStaticDoubleMethodA(env_inline_c_1,                                                        cls_inline_c_2,                                                        method_inline_c_3,                                                        cargs_inline_c_4) );
-}
-
-
-jobjectArray inline_c_Foreign_JNI_80_0b57533e83360b5a6660bf703521b3b6c2fbec66(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2, jclass cls_inline_c_3) {
-return (
-      (*env_inline_c_0)->NewObjectArray(env_inline_c_1,
-                                        sz_inline_c_2,
-                                        cls_inline_c_3,
-                                        NULL) );
-}
-
-
-jbooleanArray inline_c_Foreign_JNI_81_b1841567b8f0e99405458b9e8a3b7f3a3e20812f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewBooleanArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jbyteArray inline_c_Foreign_JNI_82_1a9345ff427557126ba3aa5f0fb460f3df632ff8(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewByteArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jcharArray inline_c_Foreign_JNI_83_b00869a9422815fdc3aa43f15e3b782dc6f19e03(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewCharArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jshortArray inline_c_Foreign_JNI_84_06a1e38de0ed2d7764757388457ed0797c72d8aa(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewShortArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jintArray inline_c_Foreign_JNI_85_af7c087746afd64be9d977ebf078c2df4b3d918e(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewIntArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jlongArray inline_c_Foreign_JNI_86_270c75c62cc97fdc3741af544fa35a61abf37fba(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewLongArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jfloatArray inline_c_Foreign_JNI_87_312dee8af1c4b2058cb1b2703277cf297ba34224(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewFloatArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jdoubleArray inline_c_Foreign_JNI_88_103070e78986a21762e18c9aebfa9162a3565d9b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jsize sz_inline_c_2) {
-return (       (*env_inline_c_0)->NewDoubleArray(env_inline_c_1,                                               sz_inline_c_2) );
-}
-
-
-jstring inline_c_Foreign_JNI_89_d5ed5b314231e7dc3292c2329a2cb4191e262633(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jchar * ptr_inline_c_2, jsize len_inline_c_3) {
-return (
-      (*env_inline_c_0)->NewString(env_inline_c_1,
-                                   ptr_inline_c_2,
-                                   len_inline_c_3) );
-}
-
-
-jsize inline_c_Foreign_JNI_90_9be0134c89fa74c4d07a2601d81d89982ce8bdf6(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2) {
-return (
-      (*env_inline_c_0)->GetArrayLength(env_inline_c_1,
-                                        array_inline_c_2) );
-}
-
-
-jsize inline_c_Foreign_JNI_91_2e55ce4ded52c43b7b69c0c49c4425aef4f8a80b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) {
-return (
-      (*env_inline_c_0)->GetStringLength(env_inline_c_1,
-                                         jstr_inline_c_2) );
-}
-
-
-jboolean * inline_c_Foreign_JNI_92_153a97a3a91d03dbe7d10fe0e3d48afaa842ee96(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetBooleanArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jbyte * inline_c_Foreign_JNI_93_b630cdc25e3d575cad69a3fc3bec490a99a6ab49(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetByteArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jchar * inline_c_Foreign_JNI_94_7c0f806fe4d40ac0c1d06b4ccccc42fdc562c8ec(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetCharArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jshort * inline_c_Foreign_JNI_95_66e42eb3b8a0e71cc0cc2b722b925689a20ed23f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetShortArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jint * inline_c_Foreign_JNI_96_9ca3666fbed332c3a833881ceba71295e27d5d16(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetIntArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jlong * inline_c_Foreign_JNI_97_3bd0969839fbd68b98c00a27f6197704f6e2718b(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetLongArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jfloat * inline_c_Foreign_JNI_98_1799b6e92e7df6d5155518d25fe2fde47055a7ff(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetFloatArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-jdouble * inline_c_Foreign_JNI_99_6b454504f66bff257e7cb14d00f7064112a8f5a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2) {
-return (       (*env_inline_c_0)->GetDoubleArrayElements(env_inline_c_1,                                                       array_inline_c_2,                                                       NULL) );
-}
-
-
-const jchar * inline_c_Foreign_JNI_100_ac075a3bdcb535575fe36c6f7b5eb3d66ace44a7(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2) {
-return (
-      (*env_inline_c_0)->GetStringChars(env_inline_c_1,
-                                        jstr_inline_c_2,
-                                        NULL) );
-}
-
-
-void inline_c_Foreign_JNI_101_c405fd2cc3cc77bea5093b022f17d3b2c443e2a2(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbooleanArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jboolean * buf_inline_c_5) {
-       (*env_inline_c_0)->SetBooleanArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_102_6aefb6e6ad5f3a169ff39bd2c3186b897bcd220f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jbyteArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jbyte * buf_inline_c_5) {
-       (*env_inline_c_0)->SetByteArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_103_a1e161a18fa39331bad743b7e07b0399b3104242(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jcharArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jchar * buf_inline_c_5) {
-       (*env_inline_c_0)->SetCharArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_104_4221edb9c7b0c1666f5952fe23aad965e2f58085(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jshortArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jshort * buf_inline_c_5) {
-       (*env_inline_c_0)->SetShortArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_105_0cf86cc89e108bd7ed150e5aad2e7d8d8f95dd7a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jintArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jint * buf_inline_c_5) {
-       (*env_inline_c_0)->SetIntArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_106_983cb43fd1962ef866086f1819815a8b05791888(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jlongArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jlong * buf_inline_c_5) {
-       (*env_inline_c_0)->SetLongArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_107_26c6b32031e2561eb5fc3b047d493c3a784bbf40(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jfloatArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jfloat * buf_inline_c_5) {
-       (*env_inline_c_0)->SetFloatArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_108_fbded71aa93cca94c495be618b75c7f610619a93(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jdoubleArray array_inline_c_2, jsize start_inline_c_3, jsize len_inline_c_4, jdouble * buf_inline_c_5) {
-       (*env_inline_c_0)->SetDoubleArrayRegion(env_inline_c_1,                                                     array_inline_c_2,                                                     start_inline_c_3,                                                     len_inline_c_4,                                                     buf_inline_c_5) ;
-}
-
-
-void inline_c_Foreign_JNI_109_5d5355f911ff38accf7df59e4f3407823efa0055(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jboolean * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseBooleanArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_110_93701f28f0a45b8531f977f3ad28d48b747bb58c(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jbyte * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseByteArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_111_d799968701da7f57e4eb07390e1efda373184222(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jchar * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseCharArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_112_03e0c5a40ab324b1c42f0b70ceaeb6b1605a0ded(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jshort * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseShortArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_113_4c2726a53e147cd6eb61733e27bfc599bc883f74(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jint * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseIntArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_114_9e1790871e959852cb5032b3f2833c370b81bb0f(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jlong * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseLongArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_115_44c06b418c79983d60f09ffc49851077b1feb632(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jfloat * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseFloatArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_116_94830601ce91790b75e74abe9c9819be2e748762(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobject array_inline_c_2, jdouble * xs_inline_c_3) {
-       (*env_inline_c_0)->ReleaseDoubleArrayElements(env_inline_c_1,                                                           array_inline_c_2,                                                           xs_inline_c_3,                                                           JNI_ABORT) ;
-}
-
-
-void inline_c_Foreign_JNI_117_7a962d5f8e6114066dca42386535e4a079022eae(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jstring jstr_inline_c_2, jchar * chars_inline_c_3) {
-
-      (*env_inline_c_0)->ReleaseStringChars(env_inline_c_1,
-                                            jstr_inline_c_2,
-                                            chars_inline_c_3) ;
-}
-
-
-jobject inline_c_Foreign_JNI_118_bb66272284cce01d85b6ec31967e1a66eae7e0c5(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jarray array_inline_c_2, jsize i_inline_c_3) {
-return (
-      (*env_inline_c_0)->GetObjectArrayElement(env_inline_c_1,
-                                               array_inline_c_2,
-                                               i_inline_c_3) );
-}
-
-
-void inline_c_Foreign_JNI_119_c069b4edd080791f4858d4a7a48b8c42c99c8e4a(JNIEnv * env_inline_c_0, JNIEnv * env_inline_c_1, jobjectArray array_inline_c_2, jsize i_inline_c_3, jobject x_inline_c_4) {
-
-      (*env_inline_c_0)->SetObjectArrayElement(env_inline_c_1,
-                                               array_inline_c_2,
-                                               i_inline_c_3,
-                                               x_inline_c_4); ;
-}
-
diff --git a/src/Foreign/JNI.cpphs b/src/Foreign/JNI.cpphs
--- a/src/Foreign/JNI.cpphs
+++ b/src/Foreign/JNI.cpphs
@@ -16,6 +16,7 @@
 
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DeriveAnyClass #-}
 {-# LANGUAGE ExplicitNamespaces #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE LambdaCase #-}
@@ -146,6 +147,7 @@
   , getArrayLength
   , getStringLength
   , ArrayCopyFailed(..)
+  , NullPointerException(..)
   , getBooleanArrayElements
   , getByteArrayElements
   , getCharArrayElements
@@ -174,21 +176,25 @@
   , releaseStringChars
   , getObjectArrayElement
   , setObjectArrayElement
+    -- * Thread management
+  , attachCurrentThreadAsDaemon
+  , detachCurrentThread
+  , runInAttachedThread
   ) where
 
+import Control.Concurrent (isCurrentThreadBound, rtsSupportsBoundThreads)
 import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, takeMVar)
-import Control.Exception (Exception, bracket, finally, throwIO)
+import Control.Exception (Exception, bracket, bracket_, catch, finally, throwIO)
 import Control.Monad (join, unless, void, when)
 import Data.Choice
 import Data.Coerce
 import Data.Int
-import Data.IORef (IORef, newIORef, readIORef, atomicModifyIORef)
+import Data.IORef (IORef, newIORef, atomicModifyIORef)
 import Data.Word
 import Data.ByteString (ByteString)
 import qualified Data.ByteString as BS
 import Data.Monoid ((<>))
 import Data.Typeable (Typeable)
-import Data.TLS.PThread
 import Foreign.C (CChar)
 import Foreign.ForeignPtr
   ( finalizeForeignPtr
@@ -199,14 +205,18 @@
 import Foreign.JNI.NativeMethod
 import Foreign.JNI.Types
 import qualified Foreign.JNI.String as JNI
+import Foreign.Marshal.Alloc (alloca)
 import Foreign.Marshal.Array
 import Foreign.Ptr (Ptr, nullPtr)
+import Foreign.Storable (peek)
 import GHC.ForeignPtr (newConcForeignPtr)
+import GHC.Stack (HasCallStack, callStack, getCallStack, prettySrcLoc)
 import qualified Language.C.Inline as C
 import qualified Language.C.Inline.Unsafe as CU
 import System.IO (fixIO)
 import System.IO.Unsafe (unsafePerformIO)
 import Prelude hiding (String)
+import qualified Prelude
 
 C.context (C.baseCtx <> C.bsCtx <> jniCtx)
 
@@ -215,6 +225,10 @@
 C.include "<errno.h>"
 C.include "<stdlib.h>"
 
+-- A thread-local variable to cache the JNI environment. Accessing this variable
+-- is faster than calling @jvm->GetEnv()@.
+$(C.verbatim "static __thread JNIEnv* jniEnv; ")
+
 -- | A JNI call may cause a (Java) exception to be raised. This module raises it
 -- as a Haskell exception wrapping the Java exception.
 newtype JVMException = JVMException JThrowable
@@ -226,9 +240,25 @@
 -- because it wanted to copy the array contents but couldn't. In this case the
 -- JVM doesn't throw OutOfMemory according to the JNI spec.
 data ArrayCopyFailed = ArrayCopyFailed
+  deriving (Exception, Show, Typeable)
+
+-- | A null reference is found where a non-null reference was expected.
+data NullPointerException = NullPointerException
+  deriving (Exception, Show, Typeable)
+
+-- | A JNI call is made from a thread not attached to the JVM.
+data ThreadNotAttached = ThreadNotAttached
+  deriving (Exception, Show, Typeable)
+
+-- | A JNI call is made from an unbound thread.
+data ThreadNotBound = ThreadNotBound
+  deriving (Exception, Show, Typeable)
+
+-- | Thrown when an JNI call is made from an unbound thread.
+data JNIError = JNIError Prelude.String Int32
   deriving (Show, Typeable)
 
-instance Exception ArrayCopyFailed
+instance Exception JNIError
 
 -- | Map Java exceptions to Haskell exceptions.
 throwIfException :: Ptr JNIEnv -> IO a -> IO a
@@ -247,6 +277,14 @@
     then throwIO ArrayCopyFailed
     else return ptr
 
+-- | Throws an error if the given reference is null, otherwise performs
+-- the given io action.
+throwIfJNull :: J ty -> IO a -> IO a
+throwIfJNull j io =
+    if j == jnull
+    then throwIO NullPointerException
+    else io
+
 -- | A read-write lock
 --
 -- Concurrent readers are allowed, but only one writer is supported.
@@ -301,40 +339,83 @@
 globalJVMLock = unsafePerformIO newRWLock
 {-# NOINLINE globalJVMLock #-}
 
--- | A global mutable cell holding the TLS variable, whose content is set once
--- for each thread.
-envTlsRef :: IORef (TLS (Ptr JNIEnv))
-{-# NOINLINE envTlsRef #-}
-envTlsRef = unsafePerformIO $ do
-    -- It doesn't matter if this computation ends up running twice, say because
-    -- of lazy blackholing.
-    !tls <- mkTLS $ [C.block| JNIEnv* {
-      jsize num_jvms;
-      JavaVM *jvm;
-      /* Assume there's at most one JVM. The current JNI spec (2016) says only
-       * one JVM per process is supported anyways. */
-      JNI_GetCreatedJavaVMs(&jvm, 1, &num_jvms);
-      JNIEnv *env;
+throwIfNotOK_ :: HasCallStack => IO Int32 -> IO ()
+throwIfNotOK_ m = m >>= \case
+  rc
+    | rc == [CU.pure| jint { JNI_OK } |] -> return ()
+    | rc == [CU.pure| jint { JNI_EDETACHED } |] -> throwIO ThreadNotAttached
+    | otherwise -> throwIO $ JNIError (prettySrcLoc loc) rc
+  where
+    (_, loc):_ = getCallStack callStack
 
-      if(!num_jvms) {
-              fprintf(stderr, "No JVM has been initialized yet.\n");
-              exit(EFAULT);
-      }
+attachCurrentThreadAsDaemon :: IO ()
+attachCurrentThreadAsDaemon = do
+    throwIfNotOK_
+      [CU.exp| jint {
+        (*$(JavaVM* jvm))->AttachCurrentThreadAsDaemon($(JavaVM* jvm), &jniEnv, NULL)
+      } |]
 
-      /* Attach as daemon to match GHC's usual semantics for threads, which are
-       * daemonic.
-       */
-      (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void**)&env, NULL);
-      return env; } |]
-    newIORef tls
+detachCurrentThread :: IO ()
+detachCurrentThread =
+    throwIfNotOK_
+    [CU.block| jint {
+      int rc = (*$(JavaVM* jvm))->DetachCurrentThread($(JavaVM* jvm));
+      if (rc == JNI_OK)
+        jniEnv = NULL;
+      return rc;
+    } |]
 
+-- | Attaches the calling thread to the JVM, runs the given IO action and
+-- then detaches the thread.
+--
+-- If the thread is already attached no attaching and detaching is performed.
+runInAttachedThread :: IO a -> IO a
+runInAttachedThread io = do
+    attached <-
+      catch (getJNIEnv >> return True) (\ThreadNotBound -> return False)
+    if attached
+    then io
+    else bracket_
+          attachCurrentThreadAsDaemon
+          detachCurrentThread
+          io
+
+-- | The current JVM
+--
+-- Assumes there's at most one JVM. The current JNI spec (2016) says only
+-- one JVM per process is supported anyways.
+{-# NOINLINE jvm #-}
+jvm :: Ptr JVM
+jvm = unsafePerformIO $ alloca $ \pjvm -> alloca $ \pnum_jvms -> do
+    throwIfNotOK_
+      [CU.exp| jint {
+        JNI_GetCreatedJavaVMs($(JavaVM** pjvm), 1, $(jsize* pnum_jvms))
+      }|]
+    num_jvms <- peek pnum_jvms
+    when (num_jvms == 0) $
+      fail "JNI_GetCreatedJavaVMs: No JVM has been initialized yet."
+    when (num_jvms > 1) $
+      fail "JNI_GetCreatedJavaVMs: There are multiple JVMs but only one is supported."
+    peek pjvm
+
+-- | Yields the JNIEnv of the calling thread.
+--
+-- Yields @Nothing@ if the calling thread is not attached to the JVM.
+getJNIEnv :: IO (Ptr JNIEnv)
+getJNIEnv = [CU.exp| JNIEnv* { jniEnv } |] >>= \case
+    env | env == nullPtr -> do
+      throwIfNotOK_
+        [CU.exp| jint {
+          (*$(JavaVM* jvm))->GetEnv($(JavaVM* jvm), (void**)&jniEnv, JNI_VERSION_1_6)
+        }|]
+      [CU.exp| JNIEnv* { jniEnv } |]
+    env -> return env
+
 -- | Run an action against the appropriate 'JNIEnv'.
 --
 -- Each OS thread has its own 'JNIEnv', which this function gives access to.
---
--- TODO check whether this call is only safe from a (bound) thread.
 withJNIEnv :: (Ptr JNIEnv -> IO a) -> IO a
-withJNIEnv f = f =<< getTLS =<< readIORef envTlsRef
+withJNIEnv f = getJNIEnv >>= f
 
 useAsCStrings :: [ByteString] -> ([Ptr CChar] -> IO a) -> IO a
 useAsCStrings strs m =
@@ -347,9 +428,9 @@
     useAsCStrings options $ \cstrs -> do
       withArray cstrs $ \(coptions :: Ptr (Ptr CChar)) -> do
         let n = fromIntegral (length cstrs) :: C.CInt
+        checkBoundness
         [C.block| JavaVM * {
           JavaVM *jvm;
-          JNIEnv *env;
           JavaVMInitArgs vm_args;
           JavaVMOption *options = malloc(sizeof(JavaVMOption) * $(int n));
           for(int i = 0; i < $(int n); i++)
@@ -358,15 +439,24 @@
           vm_args.nOptions = $(int n);
           vm_args.options = options;
           vm_args.ignoreUnrecognized = 0;
-          JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
+          JNI_CreateJavaVM(&jvm, (void**)&jniEnv, &vm_args);
           free(options);
           return jvm; } |]
 
+  where
+    checkBoundness :: IO ()
+    checkBoundness = when rtsSupportsBoundThreads $ do
+      bound <- isCurrentThreadBound
+      unless bound (throwIO ThreadNotBound)
+
 -- | Deallocate a 'JVM' created using 'newJVM'.
 destroyJVM :: JVM -> IO ()
 destroyJVM (JVM_ jvm) = do
     acquireWriteLock globalJVMLock
-    [C.block| void { (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm)); } |]
+    [C.block| void {
+        (*$(JavaVM *jvm))->DestroyJavaVM($(JavaVM *jvm));
+        jniEnv = NULL;
+    } |]
 
 -- | Create a new JVM, with the given arguments. Destroy it once the given
 -- action completes. /Can only be called once/. Best practice: use it to wrap
@@ -412,7 +502,7 @@
                                 $fptr-ptr:(jobject obj)) } |]
 
 throwNew :: JClass -> JNI.String -> IO ()
-throwNew cls msg = withJNIEnv $ \env ->
+throwNew cls msg = throwIfJNull cls $ withJNIEnv $ \env ->
     JNI.withString msg $ \msgp -> void $ do
     [CU.exp| jint {
        (*$(JNIEnv *env))->ThrowNew($(JNIEnv *env),
@@ -429,7 +519,7 @@
     [CU.exp| jclass { (*$(JNIEnv *env))->FindClass($(JNIEnv *env), $(char *namep)) } |]
 
 newObject :: JClass -> MethodSignature -> [JValue] -> IO JObject
-newObject cls (coerce -> sig) args = withJNIEnv $ \env ->
+newObject cls (coerce -> sig) args = throwIfJNull cls $ withJNIEnv $ \env ->
     throwIfException env $
     withJValues args $ \cargs -> do
       constr <- getMethodID cls "<init>" sig
@@ -444,7 +534,8 @@
   -> JNI.String -- ^ Field name
   -> Signature -- ^ JNI signature
   -> IO JFieldID
-getFieldID cls fieldname (coerce -> sig) = withJNIEnv $ \env ->
+getFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $
+    withJNIEnv $ \env ->
     throwIfException env $
     JNI.withString fieldname $ \fieldnamep ->
     JNI.withString sig $ \sigp ->
@@ -459,7 +550,8 @@
   -> JNI.String -- ^ Field name
   -> Signature -- ^ JNI signature
   -> IO JFieldID
-getStaticFieldID cls fieldname (coerce -> sig) = withJNIEnv $ \env ->
+getStaticFieldID cls fieldname (coerce -> sig) = throwIfJNull cls $
+    withJNIEnv $ \env ->
     throwIfException env $
     JNI.withString fieldname $ \fieldnamep ->
     JNI.withString sig $ \sigp ->
@@ -493,7 +585,8 @@
 
 #define GET_STATIC_FIELD(name, hs_rettype, c_rettype) \
 getStatic/**/name/**/Field :: JClass -> JFieldID -> IO hs_rettype; \
-getStatic/**/name/**/Field klass field = withJNIEnv $ \env -> \
+getStatic/**/name/**/Field klass field = throwIfJNull klass $ \
+    withJNIEnv $ \env -> \
     throwIfException env $ \
     [CU.exp| c_rettype { \
       (*$(JNIEnv *env))->GetStatic/**/name/**/Field($(JNIEnv *env), \
@@ -539,7 +632,7 @@
 
 #define SET_STATIC_FIELD(name, hs_fieldtype, c_fieldtype) \
 setStatic/**/name/**/Field :: JClass -> JFieldID -> hs_fieldtype -> IO (); \
-setStatic/**/name/**/Field klass field x = \
+setStatic/**/name/**/Field klass field x = throwIfJNull klass $ \
     withJNIEnv $ \env -> \
     throwIfException env $ \
     [CU.block| void { \
@@ -566,7 +659,8 @@
   -> JNI.String -- ^ Field name
   -> MethodSignature -- ^ JNI signature
   -> IO JMethodID
-getMethodID cls methodname (coerce -> sig) = withJNIEnv $ \env ->
+getMethodID cls methodname (coerce -> sig) = throwIfJNull cls $
+    withJNIEnv $ \env ->
     throwIfException env $
     JNI.withString methodname $ \methodnamep ->
     JNI.withString sig $ \sigp ->
@@ -581,7 +675,8 @@
   -> JNI.String -- ^ Field name
   -> MethodSignature -- ^ JNI signature
   -> IO JMethodID
-getStaticMethodID cls methodname (coerce -> sig) = withJNIEnv $ \env ->
+getStaticMethodID cls methodname (coerce -> sig) = throwIfJNull cls $
+    withJNIEnv $ \env ->
     throwIfException env $
     JNI.withString methodname $ \methodnamep ->
     JNI.withString sig $ \sigp ->
@@ -592,7 +687,8 @@
                                            $(char *sigp)) } |]
 
 getObjectClass :: Coercible o (J ty) => o -> IO JClass
-getObjectClass (coerce -> upcast -> obj) = withJNIEnv $ \env ->
+getObjectClass (coerce -> upcast -> obj) = throwIfJNull obj $
+    withJNIEnv $ \env ->
     objectFromPtr =<<
     [CU.exp| jclass {
       (*$(JNIEnv *env))->GetObjectClass($(JNIEnv *env),
@@ -704,7 +800,8 @@
 
 #define CALL_STATIC_METHOD(name, hs_rettype, c_rettype) \
 callStatic/**/name/**/Method :: JClass -> JMethodID -> [JValue] -> IO hs_rettype; \
-callStatic/**/name/**/Method cls method args = withJNIEnv $ \env -> \
+callStatic/**/name/**/Method cls method args = throwIfJNull cls $ \
+    withJNIEnv $ \env -> \
     throwIfException env $ \
     withJValues args $ \cargs -> \
     [C.exp| c_rettype { \
@@ -731,7 +828,7 @@
 CALL_STATIC_METHOD(Double, Double, jdouble)
 
 newObjectArray :: Int32 -> JClass -> IO JObjectArray
-newObjectArray sz cls = withJNIEnv $ \env ->
+newObjectArray sz cls = throwIfJNull cls $ withJNIEnv $ \env ->
     throwIfException env $
     objectFromPtr =<<
     [CU.exp| jobjectArray {
@@ -768,20 +865,22 @@
                                    $(jsize len)) } |]
 
 getArrayLength :: Coercible o (JArray a) => o -> IO Int32
-getArrayLength (coerce -> upcast -> array) = withJNIEnv $ \env ->
+getArrayLength (coerce -> upcast -> array) = throwIfJNull array $
+    withJNIEnv $ \env ->
     [C.exp| jsize {
       (*$(JNIEnv *env))->GetArrayLength($(JNIEnv *env),
                                         $fptr-ptr:(jarray array)) } |]
 
 getStringLength :: JString -> IO Int32
-getStringLength jstr = withJNIEnv $ \env ->
+getStringLength jstr = throwIfJNull jstr $ withJNIEnv $ \env ->
     [CU.exp| jsize {
       (*$(JNIEnv *env))->GetStringLength($(JNIEnv *env),
                                          $fptr-ptr:(jstring jstr)) } |]
 
 #define GET_ARRAY_ELEMENTS(name, hs_rettype, c_rettype) \
 get/**/name/**/ArrayElements :: J/**/name/**/Array -> IO (Ptr hs_rettype); \
-get/**/name/**/ArrayElements (upcast -> array) = withJNIEnv $ \env -> \
+get/**/name/**/ArrayElements (upcast -> array) = throwIfJNull array $ \
+    withJNIEnv $ \env -> \
     throwIfNull $ \
     [CU.exp| c_rettype* { \
       (*$(JNIEnv *env))->Get/**/name/**/ArrayElements($(JNIEnv *env), \
@@ -798,7 +897,7 @@
 GET_ARRAY_ELEMENTS(Double, Double, jdouble)
 
 getStringChars :: JString -> IO (Ptr Word16)
-getStringChars jstr = withJNIEnv $ \env ->
+getStringChars jstr = throwIfJNull jstr $ withJNIEnv $ \env ->
     throwIfNull $
     [CU.exp| const jchar* {
       (*$(JNIEnv *env))->GetStringChars($(JNIEnv *env),
@@ -807,7 +906,8 @@
 
 #define SET_ARRAY_REGION(name, hs_argtype, c_argtype) \
 set/**/name/**/ArrayRegion :: J/**/name/**/Array -> Int32 -> Int32 -> Ptr hs_argtype -> IO (); \
-set/**/name/**/ArrayRegion array start len buf = withJNIEnv $ \env -> \
+set/**/name/**/ArrayRegion array start len buf = throwIfJNull array $ \
+    withJNIEnv $ \env -> \
     throwIfException env $ \
     [CU.exp| void { \
       (*$(JNIEnv *env))->Set/**/name/**/ArrayRegion($(JNIEnv *env), \
@@ -827,7 +927,8 @@
 
 #define RELEASE_ARRAY_ELEMENTS(name, hs_argtype, c_argtype) \
 release/**/name/**/ArrayElements :: J/**/name/**/Array -> Ptr hs_argtype -> IO (); \
-release/**/name/**/ArrayElements (upcast -> array) xs = withJNIEnv $ \env -> \
+release/**/name/**/ArrayElements (upcast -> array) xs = throwIfJNull array $ \
+    withJNIEnv $ \env -> \
     [CU.exp| void { \
       (*$(JNIEnv *env))->Release/**/name/**/ArrayElements($(JNIEnv *env), \
                                                           $fptr-ptr:(jobject array), \
@@ -844,7 +945,7 @@
 RELEASE_ARRAY_ELEMENTS(Double, Double, jdouble)
 
 releaseStringChars :: JString -> Ptr Word16 -> IO ()
-releaseStringChars jstr chars = withJNIEnv $ \env ->
+releaseStringChars jstr chars = throwIfJNull jstr $ withJNIEnv $ \env ->
     [CU.exp| void {
       (*$(JNIEnv *env))->ReleaseStringChars($(JNIEnv *env),
                                             $fptr-ptr:(jstring jstr),
@@ -856,7 +957,8 @@
   => JArray a
   -> Int32
   -> IO o
-getObjectArrayElement (arrayUpcast -> array) i = withJNIEnv $ \env ->
+getObjectArrayElement (arrayUpcast -> array) i = throwIfJNull array $
+    withJNIEnv $ \env ->
     ( (coerce :: J a -> o)
     . (unsafeCast :: JObject -> J a)
     ) <$> (objectFromPtr =<<)
@@ -875,6 +977,7 @@
 setObjectArrayElement (arrayUpcast -> array)
                       i
                       ((coerce :: o -> J a) -> upcast -> x) =
+    throwIfJNull array $
     withJNIEnv $ \env ->
     [C.exp| void {
       (*$(JNIEnv *env))->SetObjectArrayElement($(JNIEnv *env),
