6350179 Update JNI to support new properties
authortalley
Thu, 08 Dec 2005 17:00:18 -0800
changeset 1066 7ebdc59e2074
parent 1065 1b85d3382e43
child 1067 9939ca290852
6350179 Update JNI to support new properties 6358592 availdevs doesn't report available slices of partially-available disks 6358604 Turn on DEBUG for DEBUG build 6360964 JNI has minor differences in behvior with API
usr/src/cmd/availdevs/Makefile
usr/src/cmd/availdevs/availdevs.c
usr/src/lib/libzfs_jni/Makefile.com
usr/src/lib/libzfs_jni/common/libzfs_jni_disk.c
usr/src/lib/libzfs_jni/common/libzfs_jni_diskmgt.c
usr/src/lib/libzfs_jni/common/libzfs_jni_main.c
usr/src/lib/libzfs_jni/common/libzfs_jni_property.c
--- a/usr/src/cmd/availdevs/Makefile	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/cmd/availdevs/Makefile	Thu Dec 08 17:00:18 2005 -0800
@@ -43,6 +43,7 @@
 LINTFLAGS += -xerroff=E_NAME_USED_NOT_DEF2
 
 CPPFLAGS += $(INCS) -D_LARGEFILE64_SOURCE=1 -D_REENTRANT
+$(NOT_RELEASE_BUILD) CPPFLAGS += -DDEBUG
 
 .KEEP_STATE:
 
--- a/usr/src/cmd/availdevs/availdevs.c	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/cmd/availdevs/availdevs.c	Thu Dec 08 17:00:18 2005 -0800
@@ -66,6 +66,9 @@
 	(void) snprintf(tmp, sizeof (tmp), "%llu", dp->size);
 	xmlSetProp(disk, (xmlChar *)ATTR_DISK_SIZE, (xmlChar *)tmp);
 
+	xmlSetProp(disk, (xmlChar *)ATTR_DISK_INUSE, (xmlChar *)
+	    (dp->in_use ? VAL_ATTR_TRUE : VAL_ATTR_FALSE));
+
 	if (dp->aliases != NULL) {
 		for (i = 0; dp->aliases[i] != NULL; i++) {
 			xmlNodePtr alias = xmlNewChild(
--- a/usr/src/lib/libzfs_jni/Makefile.com	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/lib/libzfs_jni/Makefile.com	Thu Dec 08 17:00:18 2005 -0800
@@ -45,6 +45,7 @@
 
 LDLIBS +=	-lc -lnvpair -ldiskmgt -lzfs
 CPPFLAGS +=	$(INCS)
+$(NOT_RELEASE_BUILD) CPPFLAGS += -DDEBUG
 
 $(LINTLIB) := SRCS=	$(SRCDIR)/$(LINTSRC)
 
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_disk.c	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_disk.c	Thu Dec 08 17:00:18 2005 -0800
@@ -56,6 +56,8 @@
 		if (slices != NULL) {
 			jstring nameUTF = (*env)->NewStringUTF(env, dp->name);
 
+			jboolean in_use = dp->in_use ? JNI_TRUE : JNI_FALSE;
+
 			jclass class_DiskDeviceBean = (*env)->FindClass(
 			    env, ZFSJNI_PACKAGE_DATA "DiskDeviceBean");
 
@@ -63,10 +65,11 @@
 			    (*env)->GetMethodID(env, class_DiskDeviceBean,
 				"<init>",
 				"(JLjava/lang/String;[Ljava/lang/String;[L"
-				ZFSJNI_PACKAGE_DATA "SliceDeviceBean;)V");
+				ZFSJNI_PACKAGE_DATA "SliceDeviceBean;Z)V");
 
 			disk = (*env)->NewObject(env, class_DiskDeviceBean,
-			    constructor, dp->size, nameUTF, aliases, slices);
+			    constructor, dp->size, nameUTF, aliases, slices,
+			    in_use);
 		}
 	}
 
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_diskmgt.c	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_diskmgt.c	Thu Dec 08 17:00:18 2005 -0800
@@ -33,12 +33,6 @@
 #include <sys/mnttab.h>
 
 /*
- * Constants
- */
-
-#define	DISK_IN_USE	12345
-
-/*
  * Function prototypes
  */
 
@@ -102,9 +96,6 @@
  *  1. Success: error is set to 0 and a dmgt_disk_t is returned
  *
  *  2. Failure: error is set to -1 and NULL is returned
- *
- *  3. In use: error is set to DISK_IN_USE and NULL is returned if all
- *     of the slices have an existing use that precludes use in ZFS
  */
 static dmgt_disk_t *
 get_disk(dm_descriptor_t disk, int *error)
@@ -148,14 +139,6 @@
 							media[0], dp->name,
 							dp->blocksize,
 							&(dp->in_use), error);
-
-						/*
-						 * If this disk has no usable
-						 * slices...
-						 */
-						if (dp->in_use) {
-							*error = DISK_IN_USE;
-						}
 					}
 					dm_free_descriptors(media);
 				}
@@ -164,10 +147,8 @@
 	}
 
 	if (*error) {
-		if (*error != DISK_IN_USE) {
-			/* Normalize error */
-			*error = -1;
-		}
+		/* Normalize error */
+		*error = -1;
 
 		if (dp != NULL) {
 			dmgt_free_disk(dp);
@@ -408,10 +389,11 @@
 						    j);
 					}
 				}
-			} else
+			} else {
 				if (slice_too_small(slice)) {
 					remove_slice_from_list(slices, i);
 				}
+			}
 		}
 	}
 
@@ -690,16 +672,29 @@
 			int online = get_disk_online(disk, &error);
 			if (!error && online) {
 				dmgt_disk_t *dp = get_disk(disk, &error);
-				if (error == DISK_IN_USE) {
-					error = 0;
-				} else
-					if (!error) {
+				if (!error) {
+					/*
+					 * If this disk or any of its
+					 * slices is usable...
+					 */
+					if (!dp->in_use ||
+					    zjni_count_elements(
+					    (void **)dp->slices) != 0) {
+
 						/* Run the given function */
 						if (func(dp, data)) {
 							error = -1;
 						}
 						dmgt_free_disk(dp);
+#ifdef DEBUG
+					} else {
+						(void) fprintf(stderr, "disk "
+						    "has no available slices: "
+						    "%s\n", dp->name);
+#endif
 					}
+
+				}
 			}
 		}
 		dm_free_descriptors(disks);
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_main.c	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_main.c	Thu Dec 08 17:00:18 2005 -0800
@@ -173,7 +173,21 @@
 Java_com_sun_zfs_common_model_SystemDataModel_getPool(JNIEnv *env,
     jobject obj, jstring poolUTF)
 {
-	return (zjni_get_Dataset(env, poolUTF, ZFS_TYPE_FILESYSTEM));
+	jobject pool = zjni_get_Dataset(env, poolUTF, ZFS_TYPE_FILESYSTEM);
+
+	/* Verify that object is Pool, not some other Dataset */
+	if (pool != NULL) {
+	    jclass class = (*env)->FindClass(
+		env, ZFSJNI_PACKAGE_DATA "Pool");
+
+	    jboolean is_pool = (*env)->IsInstanceOf(env, pool, class);
+
+	    if (is_pool != JNI_TRUE) {
+		pool = NULL;
+	    }
+	}
+
+	return (pool);
 }
 
 /*
@@ -187,6 +201,11 @@
 Java_com_sun_zfs_common_model_SystemDataModel_getFileSystems(JNIEnv *env,
     jobject obj, jstring containerUTF)
 {
+	if (containerUTF == NULL) {
+		return (Java_com_sun_zfs_common_model_SystemDataModel_getPools(
+		    env, obj));
+	}
+
 	return (zjni_get_Datasets_below(env, containerUTF,
 	    ZFS_TYPE_FILESYSTEM, ZFS_TYPE_FILESYSTEM,
 	    ZFSJNI_PACKAGE_DATA "FileSystem"));
@@ -283,8 +302,7 @@
 	}
 
 	return (zjni_get_Datasets_below(env, containerUTF,
-	    ZFS_TYPE_FILESYSTEM, ZFS_TYPE_ANY,
-	    ZFSJNI_PACKAGE_DATA "Dataset"));
+	    ZFS_TYPE_FILESYSTEM, ZFS_TYPE_ANY, ZFSJNI_PACKAGE_DATA "Dataset"));
 }
 
 /*
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_property.c	Thu Dec 08 13:38:16 2005 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_property.c	Thu Dec 08 17:00:18 2005 -0800
@@ -31,26 +31,52 @@
 #include <strings.h>
 
 /*
+ * Types
+ */
+
+/* Signature for function to convert string to a specific Java object */
+typedef jobject (*str_to_obj_f)(JNIEnv *, char *);
+
+/* Signature for function to convert uint64_t to a specific Java object */
+typedef jobject (*uint64_to_obj_f)(JNIEnv *, uint64_t);
+
+/*
+ * Describes a property and the parameters needed to create a Java
+ * Property object for it
+ */
+typedef struct custom_prop_desct {
+	zfs_prop_t prop;
+	str_to_obj_f convert_str;
+	uint64_to_obj_f convert_uint64;
+	char *propClass;
+	char *valueClass;
+} custom_prop_desct_t;
+
+/*
  * Function prototypes
  */
 
+static jobject create_BasicProperty(JNIEnv *, zfs_handle_t *,
+    zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
 static jobject create_BooleanProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
-static jobject create_ChecksumProperty(JNIEnv *, zfs_handle_t *);
-static jobject create_CompressionProperty(JNIEnv *, zfs_handle_t *);
-static jobject create_DateProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
 static jobject create_LongProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
-static jobject create_RecordSizeProperty(JNIEnv *, zfs_handle_t *);
 static jobject create_StringProperty(JNIEnv *, zfs_handle_t *, zfs_prop_t);
-static jobject str_to_checksum(JNIEnv *, char *);
-static jobject str_to_compression(JNIEnv *, char *);
+static jobject create_ObjectProperty(JNIEnv *, zfs_handle_t *,
+    zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
+static jobject create_default_BasicProperty(JNIEnv *, zfs_prop_t,
+    str_to_obj_f, uint64_to_obj_f, char *, char *);
 static jobject create_default_BooleanProperty(JNIEnv *, zfs_prop_t);
 static jobject create_default_LongProperty(JNIEnv *, zfs_prop_t);
 static jobject create_default_StringProperty(JNIEnv *, zfs_prop_t);
-static jobject create_default_MountPointProperty(JNIEnv *);
-static jobject create_default_ShareNFSProperty(JNIEnv *);
-static jobject create_default_ChecksumProperty(JNIEnv *);
-static jobject create_default_CompressionProperty(JNIEnv *);
-static jobject create_default_RecordSizeProperty(JNIEnv *);
+static jobject create_default_ObjectProperty(
+    JNIEnv *, zfs_prop_t, str_to_obj_f, uint64_to_obj_f, char *, char *);
+static jobject str_to_enum_element(JNIEnv *, char *, char *);
+static jobject str_to_aclinherit(JNIEnv *, char *);
+static jobject str_to_aclmode(JNIEnv *, char *);
+static jobject str_to_checksum(JNIEnv *, char *);
+static jobject str_to_compression(JNIEnv *, char *);
+static jobject str_to_snapdir(JNIEnv *, char *);
+static jobject str_to_string(JNIEnv *, char *);
 
 /*
  * Static data
@@ -69,8 +95,8 @@
 
 zfs_prop_t props_long[] = {
 	ZFS_PROP_AVAILABLE,
+	ZFS_PROP_CREATETXG,
 	ZFS_PROP_QUOTA,
-	/*	ZFS_PROP_RATIO, */
 	ZFS_PROP_REFERENCED,
 	ZFS_PROP_RESERVATION,
 	ZFS_PROP_USED,
@@ -80,60 +106,265 @@
 
 zfs_prop_t props_string[] = {
 	ZFS_PROP_ORIGIN,
-	/*	ZFS_PROP_TYPE, */
+	/* ZFS_PROP_TYPE, */
 	ZFS_PROP_INVAL
 };
 
+custom_prop_desct_t props_custom[] = {
+	{ ZFS_PROP_ACLINHERIT, str_to_aclinherit, NULL,
+	    ZFSJNI_PACKAGE_DATA "AclInheritProperty",
+	    ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit" },
+
+	{ ZFS_PROP_ACLMODE, str_to_aclmode, NULL,
+	    ZFSJNI_PACKAGE_DATA "AclModeProperty",
+	    ZFSJNI_PACKAGE_DATA "AclModeProperty$AclMode" },
+
+	{ ZFS_PROP_CHECKSUM, str_to_checksum, NULL,
+	    ZFSJNI_PACKAGE_DATA "ChecksumProperty",
+	    ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum" },
+
+	{ ZFS_PROP_COMPRESSION, str_to_compression, NULL,
+	    ZFSJNI_PACKAGE_DATA "CompressionProperty",
+	    ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression" },
+
+	{ ZFS_PROP_COMPRESSRATIO, NULL, zjni_long_to_Long,
+	    ZFSJNI_PACKAGE_DATA "CompressRatioProperty",
+	    "java/lang/Long" },
+
+	{ ZFS_PROP_CREATION, zjni_str_to_date, NULL,
+	    ZFSJNI_PACKAGE_DATA "CreationProperty",
+	    "java/util/Date" },
+
+	{ ZFS_PROP_MOUNTPOINT, str_to_string, NULL,
+	    ZFSJNI_PACKAGE_DATA "MountPointProperty",
+	    "java/lang/String" },
+
+	{ ZFS_PROP_RECORDSIZE, NULL, zjni_long_to_Long,
+	    ZFSJNI_PACKAGE_DATA "RecordSizeProperty",
+	    "java/lang/Long" },
+
+	{ ZFS_PROP_SHARENFS, str_to_string, NULL,
+	    ZFSJNI_PACKAGE_DATA "ShareNFSProperty",
+	    "java/lang/String" },
+
+	{ ZFS_PROP_SNAPDIR, str_to_snapdir, NULL,
+	    ZFSJNI_PACKAGE_DATA "SnapDirProperty",
+	    ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir" },
+
+	{ ZFS_PROP_VOLBLOCKSIZE, NULL, zjni_long_to_Long,
+	    ZFSJNI_PACKAGE_DATA "VolBlockSizeProperty",
+	    "java/lang/Long" },
+
+	{ ZFS_PROP_INVAL, NULL, NULL, NULL, NULL },
+};
+
 /*
  * Static functions
  */
 
 static jobject
-create_BooleanProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+create_BasicProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop,
+    str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
+    char *propClass, char *valueClass)
 {
 	jobject propertyObject = NULL;
 	char source[ZFS_MAXNAMELEN];
-	uint64_t value;
 	zfs_source_t srctype;
+	jobject propValue = NULL;
+
+	if (convert_str != NULL) {
+	    char propbuf[ZFS_MAXPROPLEN];
+	    int result = zfs_prop_get(zhp, prop, propbuf,
+		sizeof (propbuf), &srctype, source, sizeof (source), 1);
 
-	int result = zfs_prop_get_numeric(zhp, prop, &value,
-	    &srctype, source, sizeof (source));
+	    if (result == 0) {
+		propValue = convert_str(env, propbuf);
+	    }
+	} else {
+	    uint64_t value;
+	    int result = zfs_prop_get_numeric(
+		zhp, prop, &value, &srctype, source, sizeof (source));
 
-	if (result == 0) {
-		jclass class_BooleanProperty = (*env)->FindClass(env,
-		    ZFSJNI_PACKAGE_DATA "BooleanProperty");
+	    if (result == 0) {
+		propValue = convert_uint64(env, value);
+	    }
+	}
+
+	if (propValue != NULL) {
+
+		jmethodID constructor;
+		char signature[1024];
+		jclass class = (*env)->FindClass(env, propClass);
 
 		jstring propName = (*env)->NewStringUTF(
 		    env, zfs_prop_to_name(prop));
-		jobject propValue = zjni_int_to_boolean(env, value);
+
 		jboolean readOnly = zfs_prop_readonly(prop) ?
 		    JNI_TRUE : JNI_FALSE;
 
-		jmethodID constructor_BooleanProperty;
-
 		if (srctype == ZFS_SRC_INHERITED) {
 
 			jstring propSource = (*env)->NewStringUTF(env, source);
-			constructor_BooleanProperty = (*env)->GetMethodID(
-			    env, class_BooleanProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
-			    "java/lang/String;)V");
+
+			(void) snprintf(signature, sizeof (signature),
+			    "(Ljava/lang/String;L%s;ZLjava/lang/String;)V",
+			    valueClass);
+
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
 
 			propertyObject = (*env)->NewObject(
-			    env, class_BooleanProperty,
-			    constructor_BooleanProperty,
-			    propName, propValue, readOnly, propSource);
+			    env, class, constructor, propName, propValue,
+			    readOnly, propSource);
 		} else {
 			jobject lineage = zjni_get_lineage(env, srctype);
 
-			constructor_BooleanProperty = (*env)->GetMethodID(
-			    env, class_BooleanProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
-			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
+			(void) snprintf(signature, sizeof (signature),
+			    "(Ljava/lang/String;L%s;ZL"
+			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
+			    valueClass);
+
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
 
 			propertyObject = (*env)->NewObject(
-			    env, class_BooleanProperty,
-			    constructor_BooleanProperty,
+			    env, class, constructor, propName, propValue,
+			    readOnly, lineage);
+		}
+	}
+
+	return (propertyObject);
+}
+
+static jobject
+create_BooleanProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+{
+	return (create_BasicProperty(env, zhp, prop, NULL, zjni_int_to_boolean,
+	    ZFSJNI_PACKAGE_DATA "BooleanProperty", "java/lang/Boolean"));
+}
+
+static jobject
+create_LongProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+{
+	return (create_BasicProperty(env, zhp, prop, NULL, zjni_long_to_Long,
+	    ZFSJNI_PACKAGE_DATA "LongProperty", "java/lang/Long"));
+}
+
+static jobject
+create_StringProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+{
+	return (create_BasicProperty(env, zhp, prop, str_to_string, NULL,
+	    ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String"));
+}
+
+static jobject
+create_ObjectProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop,
+    str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
+    char *propClass, char *valueClass)
+{
+	jobject propertyObject = NULL;
+	char source[ZFS_MAXNAMELEN];
+	zfs_source_t srctype;
+	jobject propValue = NULL;
+
+	if (convert_str != NULL) {
+	    char propbuf[ZFS_MAXPROPLEN];
+	    int result = zfs_prop_get(zhp, prop, propbuf,
+		sizeof (propbuf), &srctype, source, sizeof (source), 1);
+
+	    if (result == 0) {
+		propValue = convert_str(env, propbuf);
+	    }
+	} else {
+	    uint64_t value;
+	    int result = zfs_prop_get_numeric(
+		zhp, prop, &value, &srctype, source, sizeof (source));
+
+	    if (result == 0) {
+		propValue = convert_uint64(env, value);
+	    }
+	}
+
+	if (propValue != NULL) {
+
+		jmethodID constructor;
+		char signature[1024];
+		jclass class = (*env)->FindClass(env, propClass);
+
+		if (srctype == ZFS_SRC_INHERITED) {
+
+			jstring propSource = (*env)->NewStringUTF(env, source);
+
+			(void) snprintf(signature, sizeof (signature),
+			    "(L%s;Ljava/lang/String;)V", valueClass);
+
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
+
+			propertyObject = (*env)->NewObject(env,
+			    class, constructor, propValue, propSource);
+
+		} else {
+			jobject lineage = zjni_get_lineage(env, srctype);
+
+			(void) snprintf(signature, sizeof (signature),
+			    "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
+			    valueClass);
+
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
+
+			propertyObject = (*env)->NewObject(env,
+			    class, constructor, propValue, lineage);
+		}
+	}
+
+	return (propertyObject);
+}
+
+static jobject
+create_default_BasicProperty(JNIEnv *env, zfs_prop_t prop,
+    str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
+    char *propClass, char *valueClass)
+{
+	jobject propertyObject = NULL;
+
+	if (!zfs_prop_readonly(prop)) {
+		jobject propValue;
+
+		if (convert_str != NULL) {
+			char propbuf[ZFS_MAXPROPLEN];
+			zfs_prop_default_string(
+			    prop, propbuf, sizeof (propbuf));
+			propValue = convert_str(env, propbuf);
+		} else {
+			uint64_t value = zfs_prop_default_numeric(prop);
+			propValue = convert_uint64(env, value);
+		}
+
+		if (propValue != NULL) {
+			char signature[1024];
+			jmethodID constructor;
+
+			jstring propName =
+			    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
+
+			jboolean readOnly = zfs_prop_readonly(prop) ?
+			    JNI_TRUE : JNI_FALSE;
+
+			jclass class = (*env)->FindClass(env, propClass);
+			jobject lineage =
+			    zjni_get_lineage(env, ZFS_SRC_DEFAULT);
+
+			(void) snprintf(signature, sizeof (signature),
+			    "(Ljava/lang/String;L%s;ZL" ZFSJNI_PACKAGE_DATA
+			    "Property$Lineage;)V", valueClass);
+
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
+
+			propertyObject = (*env)->NewObject(
+			    env, class, constructor,
 			    propName, propValue, readOnly, lineage);
 		}
 	}
@@ -142,238 +373,65 @@
 }
 
 static jobject
-create_ChecksumProperty(JNIEnv *env, zfs_handle_t *zhp)
+create_default_BooleanProperty(JNIEnv *env, zfs_prop_t prop)
 {
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, ZFS_PROP_CHECKSUM,
-	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-		jobject propValue = str_to_checksum(env, propbuf);
-
-		if (propValue != NULL) {
-
-			jclass class_ChecksumProperty = (*env)->FindClass(env,
-			    ZFSJNI_PACKAGE_DATA "ChecksumProperty");
-
-			jmethodID constructor_ChecksumProperty;
-
-			if (srctype == ZFS_SRC_INHERITED) {
+	return (create_default_BasicProperty(env, prop, NULL,
+	    zjni_int_to_boolean, ZFSJNI_PACKAGE_DATA "BooleanProperty",
+	    "java/lang/Boolean"));
+}
 
-				jstring propSource = (*env)->NewStringUTF(env,
-				    source);
-				constructor_ChecksumProperty =
-				    (*env)->GetMethodID(
-					env, class_ChecksumProperty, "<init>",
-					"(L" ZFSJNI_PACKAGE_DATA
-					"ChecksumProperty$Checksum;Ljava/lang/"
-					"String;)V");
-
-				propertyObject = (*env)->NewObject(env,
-				    class_ChecksumProperty,
-				    constructor_ChecksumProperty,
-				    propValue, propSource);
+static jobject
+create_default_LongProperty(JNIEnv *env, zfs_prop_t prop)
+{
+	return (create_default_BasicProperty(env, prop, NULL,
+	    zjni_long_to_Long, ZFSJNI_PACKAGE_DATA "LongProperty",
+	    "java/lang/Long"));
+}
 
-			} else {
-				jobject lineage =
-				    zjni_get_lineage(env, srctype);
-				constructor_ChecksumProperty =
-				    (*env)->GetMethodID(
-					env, class_ChecksumProperty, "<init>",
-					"(L" ZFSJNI_PACKAGE_DATA
-					"ChecksumProperty$Checksum;L"
-					ZFSJNI_PACKAGE_DATA
-					"Property$Lineage;)V");
-
-				propertyObject = (*env)->NewObject(env,
-				    class_ChecksumProperty,
-				    constructor_ChecksumProperty,
-				    propValue, lineage);
-			}
-		}
-	}
-
-	return (propertyObject);
+static jobject
+create_default_StringProperty(JNIEnv *env, zfs_prop_t prop)
+{
+	return (create_default_BasicProperty(env, prop, str_to_string, NULL,
+	    ZFSJNI_PACKAGE_DATA "StringProperty", "java/lang/String"));
 }
 
 static jobject
-create_CompressionProperty(JNIEnv *env, zfs_handle_t *zhp)
-{
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, ZFS_PROP_COMPRESSION,
-	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-		jobject propValue = str_to_compression(env, propbuf);
-
-		if (propValue != NULL) {
-
-			jclass class_CompressionProperty =
-			    (*env)->FindClass(env,
-				ZFSJNI_PACKAGE_DATA "CompressionProperty");
-
-			jmethodID constructor_CompressionProperty;
-
-			if (srctype == ZFS_SRC_INHERITED) {
-
-				jstring propSource = (*env)->NewStringUTF(env,
-				    source);
-				constructor_CompressionProperty =
-				    (*env)->GetMethodID(
-					env, class_CompressionProperty,
-					"<init>",
-					"(L" ZFSJNI_PACKAGE_DATA
-					"CompressionProperty$Compression;Ljava/"
-					"lang/String;)V");
-
-				propertyObject = (*env)->NewObject(env,
-				    class_CompressionProperty,
-				    constructor_CompressionProperty,
-				    propValue, propSource);
-			} else {
-				jobject lineage = zjni_get_lineage(env,
-				    srctype);
-
-				constructor_CompressionProperty =
-				    (*env)->GetMethodID(
-					env, class_CompressionProperty,
-					"<init>",
-					"(L" ZFSJNI_PACKAGE_DATA
-					"CompressionProperty$Compression;L"
-					ZFSJNI_PACKAGE_DATA
-					"Property$Lineage;)V");
-
-				propertyObject = (*env)->NewObject(env,
-				    class_CompressionProperty,
-				    constructor_CompressionProperty,
-				    propValue, lineage);
-			}
-		}
-	}
-
-	return (propertyObject);
-}
-
-static jobject
-create_DateProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+create_default_ObjectProperty(JNIEnv *env, zfs_prop_t prop,
+    str_to_obj_f convert_str, uint64_to_obj_f convert_uint64,
+    char *propClass, char *valueClass)
 {
 	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
 
-	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
-	    &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-
-		jobject propValue = zjni_str_to_date(env, propbuf);
-		if (propValue != NULL) {
-
-			jclass class_DateProperty = (*env)->FindClass(env,
-			    ZFSJNI_PACKAGE_DATA "DateProperty");
-
-			jstring propName = (*env)->NewStringUTF(
-			    env, zfs_prop_to_name(prop));
-			jboolean readOnly =
-			    zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
-
-			jmethodID constructor_DateProperty;
-
-			if (srctype == ZFS_SRC_INHERITED) {
+	if (!zfs_prop_readonly(prop)) {
+		jobject propValue;
 
-				jstring propSource = (*env)->NewStringUTF(env,
-				    source);
-				constructor_DateProperty = (*env)->GetMethodID(
-				    env, class_DateProperty, "<init>",
-				    "(Ljava/lang/String;Ljava/util/Date;ZL"
-				    "java/lang/String;)V");
-
-				propertyObject = (*env)->NewObject(
-				    env, class_DateProperty,
-				    constructor_DateProperty,
-				    propName, propValue, readOnly, propSource);
-			} else {
-				jobject lineage = zjni_get_lineage(env,
-				    srctype);
-
-				constructor_DateProperty = (*env)->GetMethodID(
-				    env, class_DateProperty, "<init>",
-				    "(Ljava/lang/String;Ljava/util/Date;ZL"
-				    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-				propertyObject = (*env)->NewObject(
-				    env, class_DateProperty,
-				    constructor_DateProperty,
-				    propName, propValue, readOnly, lineage);
-			}
+		if (convert_str != NULL) {
+			char propbuf[ZFS_MAXPROPLEN];
+			zfs_prop_default_string(
+			    prop, propbuf, sizeof (propbuf));
+			propValue = convert_str(env, propbuf);
+		} else {
+			uint64_t value = zfs_prop_default_numeric(prop);
+			propValue = convert_uint64(env, value);
 		}
-	}
 
-	return (propertyObject);
-}
-
-static jobject
-create_LongProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
-{
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
+		if (propValue != NULL) {
+			char signature[1024];
+			jmethodID constructor;
 
-	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
-	    &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-
-		jobject propValue = zjni_str_to_long(env, propbuf);
-		if (propValue != NULL) {
-
-			jclass class_LongProperty = (*env)->FindClass(env,
-			    ZFSJNI_PACKAGE_DATA "LongProperty");
-
-			jstring propName = (*env)->NewStringUTF(
-			    env, zfs_prop_to_name(prop));
-			jboolean readOnly =
-			    zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
+			jclass class = (*env)->FindClass(env, propClass);
+			jobject lineage =
+			    zjni_get_lineage(env, ZFS_SRC_DEFAULT);
 
-			jmethodID constructor_LongProperty;
-
-			if (srctype == ZFS_SRC_INHERITED) {
-
-				jstring propSource =
-				    (*env)->NewStringUTF(env, source);
-				constructor_LongProperty = (*env)->GetMethodID(
-				    env, class_LongProperty, "<init>",
-				    "(Ljava/lang/String;Ljava/lang/Long;ZL"
-				    "java/lang/String;)V");
+			(void) snprintf(signature, sizeof (signature),
+			    "(L%s;L" ZFSJNI_PACKAGE_DATA "Property$Lineage;)V",
+			    valueClass);
 
-				propertyObject = (*env)->NewObject(
-				    env, class_LongProperty,
-				    constructor_LongProperty,
-				    propName, propValue, readOnly, propSource);
-			} else {
-				jobject lineage = zjni_get_lineage(env,
-				    srctype);
+			constructor = (*env)->GetMethodID(
+			    env, class, "<init>", signature);
 
-				constructor_LongProperty = (*env)->GetMethodID(
-				    env, class_LongProperty, "<init>",
-				    "(Ljava/lang/String;Ljava/lang/Long;ZL"
-				    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-				propertyObject = (*env)->NewObject(
-				    env, class_LongProperty,
-				    constructor_LongProperty,
-				    propName, propValue, readOnly, lineage);
-			}
+			propertyObject = (*env)->NewObject(
+			    env, class, constructor, propValue, lineage);
 		}
 	}
 
@@ -381,250 +439,68 @@
 }
 
 static jobject
-create_RecordSizeProperty(JNIEnv *env, zfs_handle_t *zhp)
+str_to_enum_element(JNIEnv *env, char *str, char *valueClass)
 {
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, ZFS_PROP_RECORDSIZE,
-	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
+	char signature[1024];
+	jmethodID method_valueOf;
 
-	if (result == 0) {
-
-		jobject propValue = zjni_str_to_long(env, propbuf);
-		if (propValue != NULL) {
-
-			jclass class_RecordSizeProperty = (*env)->FindClass(env,
-			    ZFSJNI_PACKAGE_DATA "RecordSizeProperty");
-
-			jmethodID constructor_RecordSizeProperty;
-
-			if (srctype == ZFS_SRC_INHERITED) {
+	jstring utf = (*env)->NewStringUTF(env, str);
+	jclass class = (*env)->FindClass(env, valueClass);
 
-				jstring propSource =
-				    (*env)->NewStringUTF(env, source);
-				constructor_RecordSizeProperty =
-				    (*env)->GetMethodID(
-					env, class_RecordSizeProperty, "<init>",
-					"(Ljava/lang/Long;Ljava/lang/"
-					"String;)V");
-
-				propertyObject = (*env)->NewObject(env,
-				    class_RecordSizeProperty,
-				    constructor_RecordSizeProperty,
-				    propValue, propSource);
-			} else {
-				jobject lineage =
-				    zjni_get_lineage(env, srctype);
+	(void) snprintf(signature, sizeof (signature),
+	    "(Ljava/lang/String;)L%s;", valueClass);
 
-				constructor_RecordSizeProperty =
-				    (*env)->GetMethodID(
-					env, class_RecordSizeProperty, "<init>",
-					"(Ljava/lang/Long;L"
-					ZFSJNI_PACKAGE_DATA
-					"Property$Lineage;)V");
+	method_valueOf = (*env)->GetStaticMethodID(
+	    env, class, "valueOf", signature);
 
-				propertyObject = (*env)->NewObject(env,
-				    class_RecordSizeProperty,
-				    constructor_RecordSizeProperty,
-				    propValue, lineage);
-			}
-		}
-	}
-
-	return (propertyObject);
+	return (*env)->CallStaticObjectMethod(env, class, method_valueOf, utf);
 }
 
 static jobject
-create_StringProperty(JNIEnv *env, zfs_handle_t *zhp, zfs_prop_t prop)
+str_to_aclinherit(JNIEnv *env, char *str)
 {
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, prop, propbuf, sizeof (propbuf),
-	    &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-		jmethodID constructor_StringProperty;
-
-		jclass class_StringProperty =
-		    (*env)->FindClass(env, ZFSJNI_PACKAGE_DATA
-			"StringProperty");
-
-		jstring propName =
-		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
-
-		jobject propValue = (*env)->NewStringUTF(env, propbuf);
-		jboolean readOnly = zfs_prop_readonly(prop) ?
-		    JNI_TRUE : JNI_FALSE;
-
-		if (srctype == ZFS_SRC_INHERITED) {
-
-			jstring propSource = (*env)->NewStringUTF(env, source);
-			constructor_StringProperty = (*env)->GetMethodID(
-			    env, class_StringProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/String;ZL"
-			    "java/lang/String;)V");
-
-			propertyObject = (*env)->NewObject(
-			    env, class_StringProperty,
-			    constructor_StringProperty,
-			    propName, propValue, readOnly, propSource);
-		} else {
-			jobject lineage = zjni_get_lineage(env, srctype);
-
-			constructor_StringProperty = (*env)->GetMethodID(
-			    env, class_StringProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/String;ZL"
-			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-			propertyObject = (*env)->NewObject(
-			    env, class_StringProperty,
-			    constructor_StringProperty,
-			    propName, propValue, readOnly, lineage);
-		}
-	}
-
-	return (propertyObject);
+	return (str_to_enum_element(env, str,
+	    ZFSJNI_PACKAGE_DATA "AclInheritProperty$AclInherit"));
 }
 
 static jobject
-create_MountPointProperty(JNIEnv *env, zfs_handle_t *zhp)
+str_to_aclmode(JNIEnv *env, char *str)
 {
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT,
-	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-		jmethodID constructor_MountPointProperty;
-
-		jclass class_MountPointProperty = (*env)->FindClass(
-		    env, ZFSJNI_PACKAGE_DATA "MountPointProperty");
-
-		jobject propValue = (*env)->NewStringUTF(env, propbuf);
-
-		if (srctype == ZFS_SRC_INHERITED) {
-
-			jstring propSource = (*env)->NewStringUTF(env, source);
-			constructor_MountPointProperty = (*env)->GetMethodID(
-			    env, class_MountPointProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/String;)V");
-
-			propertyObject = (*env)->NewObject(env,
-			    class_MountPointProperty,
-			    constructor_MountPointProperty,
-			    propValue, propSource);
-		} else {
-			jobject lineage = zjni_get_lineage(env, srctype);
-
-			constructor_MountPointProperty = (*env)->GetMethodID(
-			    env, class_MountPointProperty, "<init>",
-			    "(Ljava/lang/String;L"
-			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-			propertyObject = (*env)->NewObject(env,
-			    class_MountPointProperty,
-			    constructor_MountPointProperty,
-			    propValue, lineage);
-		}
-	}
-
-	return (propertyObject);
-}
-
-static jobject
-create_ShareNFSProperty(JNIEnv *env, zfs_handle_t *zhp)
-{
-	jobject propertyObject = NULL;
-	char propbuf[ZFS_MAXPROPLEN];
-	char source[ZFS_MAXNAMELEN];
-	zfs_source_t srctype;
-
-	int result = zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
-	    propbuf, sizeof (propbuf), &srctype, source, sizeof (source), 1);
-
-	if (result == 0) {
-		jmethodID constructor_ShareNFSProperty;
-
-		jclass class_ShareNFSProperty = (*env)->FindClass(
-		    env, ZFSJNI_PACKAGE_DATA "ShareNFSProperty");
-
-		jobject propValue = (*env)->NewStringUTF(env, propbuf);
-
-		if (srctype == ZFS_SRC_INHERITED) {
-
-			jstring propSource = (*env)->NewStringUTF(env, source);
-			constructor_ShareNFSProperty = (*env)->GetMethodID(
-			    env, class_ShareNFSProperty, "<init>",
-			    "(Ljava/lang/String;Ljava/lang/String;)V");
-
-			propertyObject = (*env)->NewObject(
-			    env, class_ShareNFSProperty,
-			    constructor_ShareNFSProperty,
-			    propValue, propSource);
-		} else {
-			jobject lineage = zjni_get_lineage(env, srctype);
-
-			constructor_ShareNFSProperty = (*env)->GetMethodID(
-			    env, class_ShareNFSProperty, "<init>",
-			    "(Ljava/lang/String;L"
-			    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-			propertyObject = (*env)->NewObject(
-			    env, class_ShareNFSProperty,
-			    constructor_ShareNFSProperty,
-			    propValue, lineage);
-		}
-	}
-
-	return (propertyObject);
+	return (str_to_enum_element(env, str,
+	    ZFSJNI_PACKAGE_DATA "AclModeProperty$AclMode"));
 }
 
 static jobject
 str_to_checksum(JNIEnv *env, char *str)
 {
-	jclass class_Checksum = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum");
-
-	jmethodID method_valueOf = (*env)->GetStaticMethodID(
-	    env, class_Checksum, "valueOf",
-	    "(Ljava/lang/String;)L"
-	    ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum;");
-
-	jstring utf = (*env)->NewStringUTF(env, str);
-
-	return (*env)->CallStaticObjectMethod(
-	    env, class_Checksum, method_valueOf, utf);
+	return (str_to_enum_element(env, str,
+	    ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum"));
 }
 
 static jobject
 str_to_compression(JNIEnv *env, char *str)
 {
-	jclass class_Compression = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression");
+	return (str_to_enum_element(env, str,
+	    ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression"));
+}
 
-	jmethodID method_valueOf = (*env)->GetStaticMethodID(
-	    env, class_Compression, "valueOf",
-	    "(Ljava/lang/String;)L"
-	    ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression;");
+static jobject
+str_to_snapdir(JNIEnv *env, char *str)
+{
+	return (str_to_enum_element(env, str,
+	    ZFSJNI_PACKAGE_DATA "SnapDirProperty$SnapDir"));
+}
 
-	jstring utf = (*env)->NewStringUTF(env, str);
-
-	return (*env)->CallStaticObjectMethod(
-	    env, class_Compression, method_valueOf, utf);
+static jobject
+str_to_string(JNIEnv *env, char *str)
+{
+	return (*env)->NewStringUTF(env, str);
 }
 
 /*
  * Package-private functions
  */
+
 jobject
 zjni_get_default_property(JNIEnv *env, zfs_prop_t prop)
 {
@@ -647,24 +523,13 @@
 		}
 	}
 
-	if (prop == ZFS_PROP_MOUNTPOINT) {
-		return (create_default_MountPointProperty(env));
-	}
-
-	if (prop == ZFS_PROP_SHARENFS) {
-		return (create_default_ShareNFSProperty(env));
-	}
-
-	if (prop == ZFS_PROP_CHECKSUM) {
-		return (create_default_ChecksumProperty(env));
-	}
-
-	if (prop == ZFS_PROP_COMPRESSION) {
-		return (create_default_CompressionProperty(env));
-	}
-
-	if (prop == ZFS_PROP_RECORDSIZE) {
-		return (create_default_RecordSizeProperty(env));
+	for (i = 0; props_custom[i].prop != ZFS_PROP_INVAL; i++) {
+		if (prop == props_custom[i].prop) {
+		    return create_default_ObjectProperty(env,
+			props_custom[i].prop, props_custom[i].convert_str,
+			props_custom[i].convert_uint64,
+			props_custom[i].propClass, props_custom[i].valueClass);
+		}
 	}
 
 	return (NULL);
@@ -800,364 +665,30 @@
 		}
 	}
 
-	prop = create_MountPointProperty(env, zhp);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
-
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
-#ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_MOUNTPOINT),
-		    zfs_get_name(zhp));
-#endif
-	}
-
-	prop = create_ShareNFSProperty(env, zhp);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
-
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
-#ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_SHARENFS),
-		    zfs_get_name(zhp));
-#endif
-	}
-
-	prop = create_ChecksumProperty(env, zhp);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
+	for (i = 0; props_custom[i].prop != ZFS_PROP_INVAL; i++) {
+		/* Create property and add to list */
+		prop = create_ObjectProperty(env, zhp, props_custom[i].prop,
+		    props_custom[i].convert_str, props_custom[i].convert_uint64,
+		    props_custom[i].propClass, props_custom[i].valueClass);
 
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
-#ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_CHECKSUM),
-		    zfs_get_name(zhp));
-#endif
-	}
-
-	prop = create_CompressionProperty(env, zhp);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
+		/* Does this property apply to this object? */
+		if (prop != NULL) {
 
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
-#ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_COMPRESSION),
-		    zfs_get_name(zhp));
-#endif
-	}
-
-	prop = create_RecordSizeProperty(env, zhp);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
-
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
+			(*env)->CallBooleanMethod(
+			    env, ((zjni_Object_t *)proplist)->object,
+			    ((zjni_Collection_t *)proplist)->method_add, prop);
+		} else {
+			if ((*env)->ExceptionOccurred(env) != NULL) {
+				return (NULL);
+			}
 #ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_RECORDSIZE),
-		    zfs_get_name(zhp));
-#endif
-	}
-
-	prop = create_DateProperty(env, zhp, ZFS_PROP_CREATION);
-	/* Does this property apply to this object? */
-	if (prop != NULL) {
-
-		(*env)->CallBooleanMethod(env,
-		    ((zjni_Object_t *)proplist)->object,
-		    ((zjni_Collection_t *)proplist)->method_add, prop);
-	} else {
-		if ((*env)->ExceptionOccurred(env) != NULL) {
-			return (NULL);
-		}
-#ifdef	DEBUG
-		(void) fprintf(stderr, "Property %s is not appropriate "
-		    "for %s\n", zfs_prop_to_name(ZFS_PROP_CREATION),
-		    zfs_get_name(zhp));
+			(void) fprintf(stderr, "Property %s is not appropriate "
+			    "for %s\n", zfs_prop_to_name(props_custom[i].prop),
+			    zfs_get_name(zhp));
 #endif
-	}
-
-	return (zjni_Collection_to_array(
-	    env, (zjni_Collection_t *)proplist,
-	    ZFSJNI_PACKAGE_DATA "Property"));
-}
-
-static jobject
-create_default_BooleanProperty(JNIEnv *env, zfs_prop_t prop)
-{
-	jobject propertyObject = NULL;
-
-	if (!zfs_prop_readonly(prop)) {
-
-		jclass class_BooleanProperty = (*env)->FindClass(env,
-		    ZFSJNI_PACKAGE_DATA "BooleanProperty");
-
-		jmethodID constructor_BooleanProperty = (*env)->GetMethodID(
-		    env, class_BooleanProperty, "<init>",
-		    "(Ljava/lang/String;Ljava/lang/Boolean;ZL"
-		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-		jstring propName =
-		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
-		jobject propValue =
-		    zjni_int_to_boolean(env, zfs_prop_default_numeric(prop));
-		jboolean readOnly = zfs_prop_readonly(prop) ?
-		    JNI_TRUE : JNI_FALSE;
-		jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-		propertyObject = (*env)->NewObject(
-		    env, class_BooleanProperty, constructor_BooleanProperty,
-		    propName, propValue, readOnly, lineage);
-	}
-
-	return (propertyObject);
-}
-
-static jobject
-create_default_LongProperty(JNIEnv *env, zfs_prop_t prop)
-{
-	jobject propertyObject = NULL;
-
-	if (!zfs_prop_readonly(prop)) {
-
-		jclass class_LongProperty = (*env)->FindClass(env,
-		    ZFSJNI_PACKAGE_DATA "LongProperty");
-
-		jmethodID constructor_LongProperty = (*env)->GetMethodID(
-		    env, class_LongProperty, "<init>",
-		    "(Ljava/lang/String;Ljava/lang/Long;ZL"
-		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-		jstring propName =
-		    (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
-		jobject propValue =
-		    zjni_long_to_Long(env, zfs_prop_default_numeric(prop));
-		jboolean readOnly = zfs_prop_readonly(prop)
-		    ? JNI_TRUE : JNI_FALSE;
-		jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-		propertyObject = (*env)->NewObject(
-		    env, class_LongProperty, constructor_LongProperty,
-		    propName, propValue, readOnly, lineage);
+		}
 	}
 
-	return (propertyObject);
-}
-
-static jobject
-create_default_StringProperty(JNIEnv *env, zfs_prop_t prop)
-{
-	jobject propertyObject = NULL;
-
-	if (zfs_prop_is_string(prop) && !zfs_prop_readonly(prop)) {
-
-		char propbuf[ZFS_MAXPROPLEN];
-		jclass class_StringProperty;
-		jmethodID constructor_StringProperty;
-		jstring propName;
-		jobject propValue;
-		jboolean readOnly;
-		jobject lineage;
-
-		zfs_prop_default_string(prop, propbuf, sizeof (propbuf));
-
-		class_StringProperty =
-		    (*env)->FindClass(env,
-			ZFSJNI_PACKAGE_DATA "StringProperty");
-
-		constructor_StringProperty = (*env)->GetMethodID(
-		    env, class_StringProperty, "<init>",
-		    "(Ljava/lang/String;Ljava/lang/String;ZL"
-		    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-		propName = (*env)->NewStringUTF(env, zfs_prop_to_name(prop));
-		propValue = (*env)->NewStringUTF(env, propbuf);
-		readOnly = zfs_prop_readonly(prop) ? JNI_TRUE : JNI_FALSE;
-		lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-		propertyObject = (*env)->NewObject(
-		    env, class_StringProperty, constructor_StringProperty,
-		    propName, propValue, readOnly, lineage);
-	}
-
-	return (propertyObject);
-}
-
-static jobject
-create_default_MountPointProperty(JNIEnv *env)
-{
-	jobject propertyObject = NULL;
-
-	char propbuf[ZFS_MAXPROPLEN];
-	jclass class_MountPointProperty;
-	jmethodID constructor_MountPointProperty;
-	jobject propValue;
-	jobject lineage;
-
-	zfs_prop_default_string(ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf));
-
-	class_MountPointProperty = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "MountPointProperty");
-
-	propValue = (*env)->NewStringUTF(env, propbuf);
-	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-	constructor_MountPointProperty = (*env)->GetMethodID(
-	    env, class_MountPointProperty, "<init>",
-	    "(Ljava/lang/String;L"
-	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-	propertyObject = (*env)->NewObject(
-	    env, class_MountPointProperty, constructor_MountPointProperty,
-	    propValue, lineage);
-
-	return (propertyObject);
+	return (zjni_Collection_to_array(env,
+	    (zjni_Collection_t *)proplist, ZFSJNI_PACKAGE_DATA "Property"));
 }
-
-static jobject
-create_default_ShareNFSProperty(JNIEnv *env)
-{
-	jobject propertyObject = NULL;
-
-	char propbuf[ZFS_MAXPROPLEN];
-	jclass class_ShareNFSProperty;
-	jmethodID constructor_ShareNFSProperty;
-	jobject propValue;
-	jobject lineage;
-
-	zfs_prop_default_string(ZFS_PROP_SHARENFS, propbuf, sizeof (propbuf));
-
-	class_ShareNFSProperty = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "ShareNFSProperty");
-
-	propValue = (*env)->NewStringUTF(env, propbuf);
-	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-	constructor_ShareNFSProperty = (*env)->GetMethodID(
-	    env, class_ShareNFSProperty, "<init>",
-	    "(Ljava/lang/String;L"
-	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-	propertyObject = (*env)->NewObject(
-	    env, class_ShareNFSProperty, constructor_ShareNFSProperty,
-	    propValue, lineage);
-
-	return (propertyObject);
-}
-
-static jobject
-create_default_ChecksumProperty(JNIEnv *env)
-{
-	jobject propertyObject = NULL;
-
-	char propbuf[ZFS_MAXPROPLEN];
-	jclass class_ChecksumProperty;
-	jmethodID constructor_ChecksumProperty;
-	jobject propValue;
-	jobject lineage;
-
-	zfs_prop_default_string(ZFS_PROP_CHECKSUM, propbuf, sizeof (propbuf));
-	propValue = str_to_checksum(env, propbuf);
-
-	class_ChecksumProperty = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "ChecksumProperty");
-
-	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-	constructor_ChecksumProperty = (*env)->GetMethodID(
-	    env, class_ChecksumProperty, "<init>",
-	    "(L" ZFSJNI_PACKAGE_DATA "ChecksumProperty$Checksum;L"
-	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-	propertyObject = (*env)->NewObject(env,
-	    class_ChecksumProperty, constructor_ChecksumProperty,
-	    propValue, lineage);
-
-	return (propertyObject);
-}
-
-static jobject
-create_default_CompressionProperty(JNIEnv *env)
-{
-	jobject propertyObject = NULL;
-
-	char propbuf[ZFS_MAXPROPLEN];
-	jclass class_CompressionProperty;
-	jmethodID constructor_CompressionProperty;
-	jobject propValue;
-	jobject lineage;
-
-	zfs_prop_default_string(
-	    ZFS_PROP_COMPRESSION, propbuf, sizeof (propbuf));
-	propValue = str_to_compression(env, propbuf);
-
-	class_CompressionProperty = (*env)->FindClass(
-	    env, ZFSJNI_PACKAGE_DATA "CompressionProperty");
-
-	lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-	constructor_CompressionProperty = (*env)->GetMethodID(
-	    env, class_CompressionProperty, "<init>",
-	    "(L" ZFSJNI_PACKAGE_DATA "CompressionProperty$Compression;L"
-	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-	propertyObject = (*env)->NewObject(env,
-	    class_CompressionProperty, constructor_CompressionProperty,
-	    propValue, lineage);
-
-	return (propertyObject);
-}
-
-static jobject
-create_default_RecordSizeProperty(JNIEnv *env)
-{
-	jclass class_RecordSizeProperty = (*env)->FindClass(env,
-	    ZFSJNI_PACKAGE_DATA "RecordSizeProperty");
-
-	jmethodID constructor_RecordSizeProperty = (*env)->GetMethodID(
-	    env, class_RecordSizeProperty, "<init>",
-	    "(Ljava/lang/Long;L"
-	    ZFSJNI_PACKAGE_DATA "Property$Lineage;)V");
-
-	jobject propValue = zjni_long_to_Long(
-	    env, zfs_prop_default_numeric(ZFS_PROP_RECORDSIZE));
-
-	jobject lineage = zjni_get_lineage(env, ZFS_SRC_DEFAULT);
-
-	jobject propertyObject = (*env)->NewObject(
-	    env, class_RecordSizeProperty, constructor_RecordSizeProperty,
-	    propValue, lineage);
-
-	return (propertyObject);
-}