diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Preconditions.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Preconditions.java
index 67d6e6cc9f3..0cded9a5e6c 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Preconditions.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/Preconditions.java
@@ -44,6 +44,8 @@ public final class Preconditions {
private static final String VALIDATE_IS_NOT_NULL_EX_MESSAGE =
"The argument object is NULL";
+ private static final String CHECK_ARGUMENT_EX_MESSAGE =
+ "The argument expression is false";
private Preconditions() {
}
@@ -122,7 +124,7 @@ public final class Preconditions {
}
/**
- *
Preconditions that the specified argument is not {@code null},
+ * Preconditions that the specified argument is not {@code null},
* throwing a NPE exception otherwise.
*
*
The message of the exception is {@code msgSupplier.get()}.
@@ -156,8 +158,95 @@ public final class Preconditions {
return obj;
}
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(final boolean expression) {
+ if (!expression) {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the calling method.
+ *
+ * @param expression a boolean expression
+ * @param errorMessage the exception message to use if the check fails; will be converted to a
+ * string using {@link String#valueOf(Object)}
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(final boolean expression, final Object errorMessage) {
+ if (!expression) {
+ throw new IllegalArgumentException(String.valueOf(errorMessage));
+ }
+ }
+
+ /**
+ * Ensures the truth of an expression involving one or more parameters to the calling method.
+ *
+ * The message of the exception is {@code String.format(f, m)}.
+ *
+ * @param expression a boolean expression
+ * @param errorMsg the {@link String#format(String, Object...)}
+ * exception message if valid. Otherwise,
+ * the message is {@link #CHECK_ARGUMENT_EX_MESSAGE}
+ * @param errorMsgArgs the optional values for the formatted exception message.
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(
+ final boolean expression,
+ final String errorMsg,
+ Object... errorMsgArgs) {
+ if (!expression) {
+ String msg;
+ try {
+ msg = String.format(errorMsg, errorMsgArgs);
+ } catch (Exception e) {
+ LOG.debug("Error formatting message", e);
+ msg = CHECK_ARGUMENT_EX_MESSAGE;
+ }
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
+ /**
+ * Preconditions that the expression involving one or more parameters to the calling method.
+ *
+ * The message of the exception is {@code msgSupplier.get()}.
+ *
+ * @param expression a boolean expression
+ * @param msgSupplier the {@link Supplier#get()} set the
+ * exception message if valid. Otherwise,
+ * the message is {@link #CHECK_ARGUMENT_EX_MESSAGE}
+ * @throws IllegalArgumentException if {@code expression} is false
+ */
+ public static void checkArgument(
+ final boolean expression,
+ final Supplier msgSupplier) {
+ if (!expression) {
+ String msg;
+ try {
+ // note that we can get NPE evaluating the message itself;
+ // but we do not want this to override the actual NPE.
+ msg = msgSupplier.get();
+ } catch (Exception e) {
+ LOG.debug("Error formatting message", e);
+ msg = CHECK_ARGUMENT_EX_MESSAGE;
+ }
+ throw new IllegalArgumentException(msg);
+ }
+ }
+
/* @VisibleForTesting */
static String getDefaultNullMSG() {
return VALIDATE_IS_NOT_NULL_EX_MESSAGE;
}
+
+ /* @VisibleForTesting */
+ static String getDefaultCheckArgumentMSG() {
+ return CHECK_ARGUMENT_EX_MESSAGE;
+ }
}
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestPreconditions.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestPreconditions.java
index 7feffc31631..47917662ad4 100644
--- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestPreconditions.java
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/util/TestPreconditions.java
@@ -18,6 +18,8 @@
package org.apache.hadoop.util;
+import java.util.function.Supplier;
+
import org.junit.Test;
import org.apache.hadoop.test.LambdaTestUtils;
@@ -119,4 +121,104 @@ public class TestPreconditions {
() -> Preconditions.checkNotNull(null,
() -> String.format(NULL_FORMATTER, NON_NULL_STRING)));
}
+
+ @Test
+ public void testCheckArgumentWithSuccess() throws Exception {
+ // success
+ Preconditions.checkArgument(true);
+ // null supplier
+ Preconditions.checkArgument(true, null);
+ // null message
+ Preconditions.checkArgument(true, (String) null);
+ Preconditions.checkArgument(true, NON_NULL_STRING);
+ // null in string format
+ Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS, null, null);
+ // illegalformat
+ Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS, 1, 2);
+ // ill-formated string supplier
+ Preconditions.checkArgument(true, ()-> String.format("%d",
+ NON_INT_STRING));
+ // null pattern to string formatter
+ Preconditions.checkArgument(true, NULL_FORMATTER, null, 1);
+ // null arguments to string formatter
+ Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS,
+ null, null);
+ // illegal format exception
+ Preconditions.checkArgument(true, "message %d %d",
+ NON_INT_STRING, 1);
+ // insufficient arguments
+ Preconditions.checkArgument(true, EXPECTED_ERROR_MSG_ARGS,
+ NON_INT_STRING);
+ // null format in string supplier
+ Preconditions.checkArgument(true,
+ () -> String.format(NULL_FORMATTER, NON_INT_STRING));
+ }
+
+ @Test
+ public void testCheckArgumentWithFailure() throws Exception {
+ // failure without message
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ () -> Preconditions.checkArgument(false));
+ errorMessage = null;
+ // failure with Null message
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ null,
+ () -> Preconditions.checkArgument(false, errorMessage));
+ // failure with message
+ errorMessage = EXPECTED_ERROR_MSG;
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ errorMessage,
+ () -> Preconditions.checkArgument(false, errorMessage));
+
+ // failure with message format
+ errorMessage = EXPECTED_ERROR_MSG + " %s";
+ String arg = "IllegalArgExcep";
+ String expectedMSG = String.format(errorMessage, arg);
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ expectedMSG,
+ () -> Preconditions.checkArgument(false, errorMessage, arg));
+
+ // failure with multiple arg message format
+ errorMessage = EXPECTED_ERROR_MSG_ARGS;
+ expectedMSG =
+ String.format(errorMessage, arg, 1);
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ expectedMSG,
+ () -> Preconditions.checkArgument(false, errorMessage, arg, 1));
+
+ // ignore illegal format will be thrown if the case is not handled correctly
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ Preconditions.getDefaultCheckArgumentMSG(),
+ () -> Preconditions.checkArgument(false,
+ errorMessage, 1, NON_INT_STRING));
+
+ // ignore illegal format will be thrown for insufficient Insufficient Args
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ Preconditions.getDefaultCheckArgumentMSG(),
+ () -> Preconditions.checkArgument(false, errorMessage, NON_NULL_STRING));
+
+ // failure with Null supplier
+ final Supplier nullSupplier = null;
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ null,
+ () -> Preconditions.checkArgument(false, nullSupplier));
+
+ // ignore illegal format in supplier
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ Preconditions.getDefaultCheckArgumentMSG(),
+ () -> Preconditions.checkArgument(false,
+ () -> String.format(errorMessage, 1, NON_INT_STRING)));
+
+ // ignore insufficient arguments in string Supplier
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ Preconditions.getDefaultCheckArgumentMSG(),
+ () -> Preconditions.checkArgument(false,
+ () -> String.format(errorMessage, NON_NULL_STRING)));
+
+ // ignore null formatter
+ LambdaTestUtils.intercept(IllegalArgumentException.class,
+ Preconditions.getDefaultCheckArgumentMSG(),
+ () -> Preconditions.checkArgument(false,
+ () -> String.format(NULL_FORMATTER, NON_NULL_STRING)));
+ }
}