From 78c4623235ea54ec2adc9d079e9f5c9e87f870ba Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 6 Aug 2018 13:15:50 -0500 Subject: HDFFV-10544 Improve JNI exception handling --- .../hdf5lib/exceptions/HDF5LibraryException.java | 23 ++++-- java/src/jni/exceptionImp.c | 19 +++-- java/src/jni/exceptionImp.h | 8 +- java/src/jni/h5aImp.c | 12 ++- java/src/jni/h5dImp.c | 8 +- java/src/jni/h5eImp.c | 8 +- java/src/jni/h5lImp.c | 8 +- java/src/jni/h5oImp.c | 87 +++++++++++++--------- release_docs/RELEASE.txt | 16 +++- 9 files changed, 123 insertions(+), 66 deletions(-) diff --git a/java/src/hdf/hdf5lib/exceptions/HDF5LibraryException.java b/java/src/hdf/hdf5lib/exceptions/HDF5LibraryException.java index 5ae977d..3a1361a 100644 --- a/java/src/hdf/hdf5lib/exceptions/HDF5LibraryException.java +++ b/java/src/hdf/hdf5lib/exceptions/HDF5LibraryException.java @@ -30,6 +30,9 @@ import hdf.hdf5lib.HDF5Constants; @SuppressWarnings("serial") public class HDF5LibraryException extends HDF5Exception { + private final long majorErrorNumber; + private final long minorErrorNumber; + /** * Constructs an HDF5LibraryException with no specified detail * message. @@ -44,9 +47,10 @@ public class HDF5LibraryException extends HDF5Exception { } catch (Exception e) { } - ; - detailMessage = getMinorError(getMinorErrorNumber()); + this.majorErrorNumber = _getMajorErrorNumber(); + this.minorErrorNumber = _getMinorErrorNumber(); + detailMessage = getMinorError(minorErrorNumber); } /** @@ -65,7 +69,8 @@ public class HDF5LibraryException extends HDF5Exception { } catch (Exception e) { } - ; + this.majorErrorNumber = _getMajorErrorNumber(); + this.minorErrorNumber = _getMinorErrorNumber(); } /** @@ -74,7 +79,11 @@ public class HDF5LibraryException extends HDF5Exception { * * @return the major error number */ - public native long getMajorErrorNumber(); + public long getMajorErrorNumber() + { + return majorErrorNumber; + } + private native long _getMajorErrorNumber(); /** * Get the minor error number of the first error on the HDF5 library error @@ -82,7 +91,11 @@ public class HDF5LibraryException extends HDF5Exception { * * @return the minor error number */ - public native long getMinorErrorNumber(); + public long getMinorErrorNumber() + { + return minorErrorNumber; + } + private native long _getMinorErrorNumber(); /** * Return a error message for the minor error number. diff --git a/java/src/jni/exceptionImp.c b/java/src/jni/exceptionImp.c index afad5d5..ccda0d2 100644 --- a/java/src/jni/exceptionImp.c +++ b/java/src/jni/exceptionImp.c @@ -83,11 +83,16 @@ typedef struct H5E_num_t { } \ jm = ENVPTR->GetMethodID(ENVPAR jc, "", "(Ljava/lang/String;)V"); \ if (jm == NULL) { \ + printf("THROWEXCEPTION FATAL ERROR: GetMethodID failed\n"); \ return JNI_FALSE; \ } \ ex = ENVPTR->NewObjectA (ENVPAR jc, jm, (jvalue*)(args)); \ + if (ex == NULL) { \ + printf("THROWEXCEPTION FATAL ERROR: %s: Creation failed\n", (className)); \ + return JNI_FALSE; \ + } \ if (ENVPTR->Throw(ENVPAR (jthrowable)ex) < 0) { \ - printf("FATAL ERROR: %s: Throw failed\n", (className)); \ + printf("THROWEXCEPTION FATAL ERROR: %s: Throw failed\n", (className)); \ return JNI_FALSE; \ } \ return JNI_TRUE; \ @@ -174,13 +179,13 @@ Java_hdf_hdf5lib_exceptions_HDF5LibraryException_printStackTrace0 /* * Class: hdf_hdf5lib_exceptions_HDFLibraryException - * Method: getMajorErrorNumber + * Method: _getMajorErrorNumber * Signature: ()J * * Extract the HDF-5 major error number from the HDF-5 error stack. */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMajorErrorNumber +Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMajorErrorNumber (JNIEnv *env, jobject obj) { H5E_num_t err_nums; @@ -190,17 +195,17 @@ Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMajorErrorNumber H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, walk_error_callback, &err_nums); return err_nums.maj_num; -} /* end Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMajorErrorNumber() */ +} /* end Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMajorErrorNumber() */ /* * Class: hdf_hdf5lib_exceptions_HDFLibraryException - * Method: getMinorErrorNumber + * Method: _getMinorErrorNumber * Signature: ()J * * Extract the HDF-5 minor error number from the HDF-5 error stack. */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMinorErrorNumber +Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMinorErrorNumber (JNIEnv *env, jobject obj) { H5E_num_t err_nums; @@ -210,7 +215,7 @@ Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMinorErrorNumber H5Ewalk2(H5E_DEFAULT, H5E_WALK_DOWNWARD, walk_error_callback, &err_nums); return err_nums.min_num; -} /* end Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMinorErrorNumber() */ +} /* end Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMinorErrorNumber() */ /* * Routine to raise particular Java exceptions from C diff --git a/java/src/jni/exceptionImp.h b/java/src/jni/exceptionImp.h index 423e537..5873202 100644 --- a/java/src/jni/exceptionImp.h +++ b/java/src/jni/exceptionImp.h @@ -55,20 +55,20 @@ Java_hdf_hdf5lib_exceptions_HDF5LibraryException_printStackTrace0 /* * Class: hdf_hdf5lib_exceptions_HDFLibraryException - * Method: getMajorErrorNumber + * Method: _getMajorErrorNumber * Signature: ()J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMajorErrorNumber +Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMajorErrorNumber (JNIEnv *env, jobject obj); /* * Class: hdf_hdf5lib_exceptions_HDFLibraryException - * Method: getMinorErrorNumber + * Method: _getMinorErrorNumber * Signature: ()J */ JNIEXPORT jlong JNICALL -Java_hdf_hdf5lib_exceptions_HDF5LibraryException_getMinorErrorNumber +Java_hdf_hdf5lib_exceptions_HDF5LibraryException__1getMinorErrorNumber (JNIEnv *env, jobject obj); #ifdef __cplusplus diff --git a/java/src/jni/h5aImp.c b/java/src/jni/h5aImp.c index 13f5207..c0dc182 100644 --- a/java/src/jni/h5aImp.c +++ b/java/src/jni/h5aImp.c @@ -966,7 +966,7 @@ Java_hdf_hdf5lib_H5_H5Aget_1info_1by_1idx UNPIN_JAVA_STRING(obj_name, aName); if (status < 0) { - h5libraryError(env); + h5libraryError(env); } /* end if */ else { args[0].z = ainfo.corder_valid; @@ -1002,7 +1002,7 @@ Java_hdf_hdf5lib_H5_H5Aget_1info_1by_1name UNPIN_JAVA_STRING_TWO(obj_name, aName, attr_name, attrName); if (status < 0) { - h5libraryError(env); + h5libraryError(env); } /* end if */ else { args[0].z = ainfo.corder_valid; @@ -1166,8 +1166,12 @@ H5A_iterate_cb constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(ZJIJ)V"); if (constructor != 0) { cb_info_t = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + if (cb_info_t == NULL) { + printf("FATAL ERROR: hdf/hdf5lib/structs/H5A_info_t: Creation failed\n"); + } + else { + status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + } } /* end if (constructor != 0) */ } /* end if (cls != 0) */ } /* end if (mid != 0) */ diff --git a/java/src/jni/h5dImp.c b/java/src/jni/h5dImp.c index d7f1b57..cea6bb4 100644 --- a/java/src/jni/h5dImp.c +++ b/java/src/jni/h5dImp.c @@ -1343,7 +1343,7 @@ Java_hdf_hdf5lib_H5_H5DwriteVL htri_t isVlenStr = 0; htri_t isComplex = 0; - if (buf == NULL) { + if (buf == NULL) { h5nullArgument(env, "H5DwriteVL: buf is NULL"); } /* end if */ else { @@ -1362,14 +1362,10 @@ Java_hdf_hdf5lib_H5_H5DwriteVL isVlenStr = 1; /* strings created by H5Tvlen_create(H5T_C_S1) */ } if (isStr == 0 || isComplex>0 || isVlenStr) { - h5unimplemented(env, "H5DwriteVL: VL types, which are not string type, not implemented"); - status = -1; -#ifdef notdef status = H5DwriteVL_asstr(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, (hid_t)xfer_plist_id, buf); -#endif - } + } else if (isStr > 0) { status = H5DwriteVL_str(env, (hid_t)dataset_id, (hid_t)mem_type_id, (hid_t)mem_space_id, (hid_t)file_space_id, diff --git a/java/src/jni/h5eImp.c b/java/src/jni/h5eImp.c index 24ddcbc..10a02b0 100644 --- a/java/src/jni/h5eImp.c +++ b/java/src/jni/h5eImp.c @@ -508,8 +508,12 @@ H5E_walk_cb constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(JJJILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); if (constructor != 0) { cb_info_t = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, nindx, cb_info_t, op_data); + if (cb_info_t == NULL) { + printf("FATAL ERROR: hdf/hdf5lib/structs/H5E_error2_t: Creation failed\n"); + } + else { + status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, nindx, cb_info_t, op_data); + } } /* end if (constructor != 0) */ } /* end if(cls != 0) */ } /* end if (mid != 0) */ diff --git a/java/src/jni/h5lImp.c b/java/src/jni/h5lImp.c index ac71845..f1734fd 100644 --- a/java/src/jni/h5lImp.c +++ b/java/src/jni/h5lImp.c @@ -574,8 +574,12 @@ H5L_iterate_cb constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(IZJIJ)V"); if (constructor != 0) { cb_info_t = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + if (cb_info_t == NULL) { + printf("FATAL ERROR: hdf/hdf5lib/structs/H5L_info_t: Creation failed\n"); + } + else { + status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + } } /* end if */ } /* end if */ } /* end if */ diff --git a/java/src/jni/h5oImp.c b/java/src/jni/h5oImp.c index 7665c70..6093e46 100644 --- a/java/src/jni/h5oImp.c +++ b/java/src/jni/h5oImp.c @@ -372,41 +372,58 @@ H5O_iterate_cb constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(IIIIJJJJJJ)V"); if (constructor != 0) { hdrinfobuf = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - args[0].j = (jlong)info->meta_size.obj.index_size; - args[1].j = (jlong)info->meta_size.obj.heap_size; - // get a reference to the H5_ih_info_t class - cls = CBENVPTR->FindClass(CBENVPAR "hdf/hdf5lib/structs/H5_ih_info_t"); - if (cls != 0) { - // get a reference to the constructor; the name is - constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(JJ)V"); - if (constructor != 0) { - ihinfobuf1 = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - args[0].j = (jlong)info->meta_size.attr.index_size; - args[1].j = (jlong)info->meta_size.attr.heap_size; - ihinfobuf2 = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - args[0].j = (jlong)info->fileno; - args[1].j = (jlong)info->addr; - args[2].i = info->type; - args[3].i = (jint)info->rc; - args[4].j = (jlong)info->num_attrs; - args[5].j = info->atime; - args[6].j = info->mtime; - args[7].j = info->ctime; - args[8].j = info->btime; - args[9].l = hdrinfobuf; - args[10].l = ihinfobuf1; - args[11].l = ihinfobuf2; - // get a reference to the H5O_info_t class - cls = CBENVPTR->FindClass(CBENVPAR "hdf/hdf5lib/structs/H5O_info_t"); - if (cls != 0) { - // get a reference to the constructor; the name is - constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V"); - if (constructor != 0) { - cb_info_t = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); - - status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + if (hdrinfobuf == NULL) { + printf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5O_hdr_info_t: Creation failed\n"); + } + else { + args[0].j = (jlong)info->meta_size.obj.index_size; + args[1].j = (jlong)info->meta_size.obj.heap_size; + // get a reference to the H5_ih_info_t class + cls = CBENVPTR->FindClass(CBENVPAR "hdf/hdf5lib/structs/H5_ih_info_t"); + if (cls != 0) { + // get a reference to the constructor; the name is + constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(JJ)V"); + if (constructor != 0) { + ihinfobuf1 = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); + if (ihinfobuf1 == NULL) { + printf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5_ih_info_t: Creation failed\n"); + } + else { + args[0].j = (jlong)info->meta_size.attr.index_size; + args[1].j = (jlong)info->meta_size.attr.heap_size; + ihinfobuf2 = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); + if (ihinfobuf2 == NULL) { + printf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5_ih_info_t: Creation failed\n"); + } + else { + args[0].j = (jlong)info->fileno; + args[1].j = (jlong)info->addr; + args[2].i = info->type; + args[3].i = (jint)info->rc; + args[4].j = (jlong)info->num_attrs; + args[5].j = info->atime; + args[6].j = info->mtime; + args[7].j = info->ctime; + args[8].j = info->btime; + args[9].l = hdrinfobuf; + args[10].l = ihinfobuf1; + args[11].l = ihinfobuf2; + // get a reference to the H5O_info_t class + cls = CBENVPTR->FindClass(CBENVPAR "hdf/hdf5lib/structs/H5O_info_t"); + if (cls != 0) { + // get a reference to the constructor; the name is + constructor = CBENVPTR->GetMethodID(CBENVPAR cls, "", "(JJIIJJJJJLhdf/hdf5lib/structs/H5O_hdr_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;Lhdf/hdf5lib/structs/H5_ih_info_t;)V"); + if (constructor != 0) { + cb_info_t = CBENVPTR->NewObjectA(CBENVPAR cls, constructor, args); + if (cb_info_t == NULL) { + printf("H5O_iterate_cb ERROR: hdf/hdf5lib/structs/H5O_info_t: Creation failed\n"); + } + else { + status = CBENVPTR->CallIntMethod(CBENVPAR visit_callback, mid, g_id, str, cb_info_t, op_data); + } + } + } + } } } } diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 26ec906..0ff3220 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -164,11 +164,25 @@ Bug Fixes since HDF5-1.10.2 release Library ------- + - Java HDF5LibraryException class + + The error minor and major values would be lost after the + constructor executed. + + Created two local class variables to hold the values obtained during + execution of the constructor. Refactored the class functions to retrieve + the class values rather then calling the native functions. + The native functions were renamed and called only during execution + of the constructor. + Added error checking to calling class constructors in JNI classes. + + (ADB - 2018/08/06, HDFFV-10544) + - H5Adelete H5Adelete failed when deleting the last "large" attribute that is stored densely via fractal heap/v2 b-tree. - + After removing the attribute, update the ainfo message. If the number of attributes goes to zero, remove the message. -- cgit v0.12