diff --git a/docs/pages/pmd/rules/java.md b/docs/pages/pmd/rules/java.md
index eea3a593fd..2e0c0f89b5 100644
--- a/docs/pages/pmd/rules/java.md
+++ b/docs/pages/pmd/rules/java.md
@@ -161,6 +161,7 @@ folder: pmd/rules
* [NcssTypeCount](pmd_rules_java_design.html#ncsstypecount): Deprecated This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of l...
* [NPathComplexity](pmd_rules_java_design.html#npathcomplexity): The NPath complexity of a method is the number of acyclic execution paths through that method.Whi...
* [SignatureDeclareThrowsException](pmd_rules_java_design.html#signaturedeclarethrowsexception): A method/constructor shouldn't explicitly throw the generic java.lang.Exception, since itis uncle...
+* [SignatureDeclareThrowsRuntimeException](pmd_rules_java_design.html#signaturedeclarethrowsruntimeexception): A method/constructor should not explicitly declare java.lang.RuntimeException or it's subclasses ...
* [SimplifiedTernary](pmd_rules_java_design.html#simplifiedternary): Look for ternary operators with the form 'condition ? literalBoolean : foo'or 'condition ? foo : ...
* [SimplifyBooleanAssertion](pmd_rules_java_design.html#simplifybooleanassertion): Avoid negation in an assertTrue or assertFalse test.For example, rephrase: assertTrue(!expr);a...
* [SimplifyBooleanExpressions](pmd_rules_java_design.html#simplifybooleanexpressions): Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.
diff --git a/docs/pages/pmd/rules/java/design.md b/docs/pages/pmd/rules/java/design.md
index 3f9254ba7d..7f5112df3a 100644
--- a/docs/pages/pmd/rules/java/design.md
+++ b/docs/pages/pmd/rules/java/design.md
@@ -5,7 +5,7 @@ permalink: pmd_rules_java_design.html
folder: pmd/rules/java
sidebaractiveurl: /pmd_rules_java.html
editmepath: ../pmd-java/src/main/resources/category/java/design.xml
-keywords: Design, AbstractClassWithoutAnyMethod, AvoidCatchingGenericException, AvoidDeeplyNestedIfStmts, AvoidRethrowingException, AvoidThrowingNewInstanceOfSameException, AvoidThrowingNullPointerException, AvoidThrowingRawExceptionTypes, ClassWithOnlyPrivateConstructorsShouldBeFinal, CollapsibleIfStatements, CouplingBetweenObjects, CyclomaticComplexity, DataClass, DoNotExtendJavaLangError, ExceptionAsFlowControl, ExcessiveClassLength, ExcessiveImports, ExcessiveMethodLength, ExcessiveParameterList, ExcessivePublicCount, FinalFieldCouldBeStatic, GodClass, ImmutableField, LawOfDemeter, LogicInversion, LoosePackageCoupling, ModifiedCyclomaticComplexity, NcssConstructorCount, NcssCount, NcssMethodCount, NcssTypeCount, NPathComplexity, SignatureDeclareThrowsException, SimplifiedTernary, SimplifyBooleanAssertion, SimplifyBooleanExpressions, SimplifyBooleanReturns, SimplifyConditional, SingularField, StdCyclomaticComplexity, SwitchDensity, TooManyFields, TooManyMethods, UselessOverridingMethod, UseObjectForClearerAPI, UseUtilityClass
+keywords: Design, AbstractClassWithoutAnyMethod, AvoidCatchingGenericException, AvoidDeeplyNestedIfStmts, AvoidRethrowingException, AvoidThrowingNewInstanceOfSameException, AvoidThrowingNullPointerException, AvoidThrowingRawExceptionTypes, ClassWithOnlyPrivateConstructorsShouldBeFinal, CollapsibleIfStatements, CouplingBetweenObjects, CyclomaticComplexity, DataClass, DoNotExtendJavaLangError, ExceptionAsFlowControl, ExcessiveClassLength, ExcessiveImports, ExcessiveMethodLength, ExcessiveParameterList, ExcessivePublicCount, FinalFieldCouldBeStatic, GodClass, ImmutableField, LawOfDemeter, LogicInversion, LoosePackageCoupling, ModifiedCyclomaticComplexity, NcssConstructorCount, NcssCount, NcssMethodCount, NcssTypeCount, NPathComplexity, SignatureDeclareThrowsException, SignatureDeclareThrowsRuntimeException, SimplifiedTernary, SimplifyBooleanAssertion, SimplifyBooleanExpressions, SimplifyBooleanReturns, SimplifyConditional, SingularField, StdCyclomaticComplexity, SwitchDensity, TooManyFields, TooManyMethods, UselessOverridingMethod, UseObjectForClearerAPI, UseUtilityClass
language: Java
---
@@ -1343,6 +1343,28 @@ public void foo() throws Exception {
```
+## SignatureDeclareThrowsRuntimeException
+
+**Since:** PMD 1.2
+
+**Priority:** Medium (3)
+
+A method/constructor should not explicitly declare java.lang.RuntimeException or it's subclasses in throws clause of it's signature, since it is advised to avoid declaring unchecked exceptions in method signature.
+
+**This rule is defined by the following Java class:** [net.sourceforge.pmd.lang.java.rule.design.SignatureDeclareThrowsRuntimeExceptionRule](https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionRule.java)
+
+**Example(s):**
+
+``` java
+public void foo() throws RuntimeException {
+}
+```
+
+**Use this rule by referencing it:**
+``` xml
+
+```
+
## SimplifiedTernary
**Since:** PMD 5.4.0
diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionRule.java
new file mode 100644
index 0000000000..0680c45919
--- /dev/null
+++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionRule.java
@@ -0,0 +1,81 @@
+/**
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.java.rule.design;
+
+import java.util.Collections;
+import java.util.List;
+
+import net.sourceforge.pmd.lang.ast.Node;
+import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
+import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
+import net.sourceforge.pmd.lang.java.ast.ASTName;
+import net.sourceforge.pmd.lang.java.ast.ASTNameList;
+import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
+import net.sourceforge.pmd.lang.java.typeresolution.TypeHelper;
+
+/**
+ * A method/constructor should not explicitly declare java.lang.RuntimeException or
+ * it's subclasses in throws clause of it's signature, since it is advised to avoid
+ * declaring unchecked exceptions in method signature.
+ *
+ * @author Bhanu Prakash Pamidi
+ */
+public class SignatureDeclareThrowsRuntimeExceptionRule extends AbstractJavaRule {
+
+ @Override
+ public Object visit(ASTMethodDeclaration methodDeclaration, Object o) {
+ checkExceptions(methodDeclaration, o);
+ return super.visit(methodDeclaration, o);
+ }
+
+
+ @Override
+ public Object visit(ASTConstructorDeclaration constructorDeclaration, Object o) {
+ checkExceptions(constructorDeclaration, o);
+ return super.visit(constructorDeclaration, o);
+ }
+
+ /**
+ * Search the list of thrown exceptions for Exception
+ */
+ private void checkExceptions(Node method, Object o) {
+ List exceptionList = Collections.emptyList();
+ ASTNameList nameList = method.getFirstChildOfType(ASTNameList.class);
+ if (nameList != null) {
+ exceptionList = nameList.findDescendantsOfType(ASTName.class);
+ }
+ if (!exceptionList.isEmpty()) {
+ evaluateExceptions(exceptionList, o);
+ }
+ }
+
+ /**
+ * Checks all exceptions for possible violation on the exception
+ * declaration.
+ *
+ * @param exceptionList
+ * containing all exception for declaration
+ * @param context
+ */
+ private void evaluateExceptions(List exceptionList, Object context) {
+ for (ASTName exception : exceptionList) {
+ if (hasDeclaredRunTimeExceptionInSignature(exception)) {
+ addViolation(context, exception);
+ }
+ }
+ }
+
+ /**
+ * Checks if the given value is defined as Exception
and the
+ * parent is either a method or constructor declaration.
+ *
+ * @param exception
+ * to evaluate
+ * @return true if Exception
is declared and has proper parents
+ */
+ private boolean hasDeclaredRunTimeExceptionInSignature(ASTName exception) {
+ return exception.getType() != null && TypeHelper.isA(exception, RuntimeException.class);
+ }
+}
diff --git a/pmd-java/src/main/resources/category/java/design.xml b/pmd-java/src/main/resources/category/java/design.xml
index 25062f3eb1..26eb6e2322 100644
--- a/pmd-java/src/main/resources/category/java/design.xml
+++ b/pmd-java/src/main/resources/category/java/design.xml
@@ -1136,6 +1136,24 @@ derived from RuntimeException or a checked exception.
+
+
+
+
+
+A method/constructor should not explicitly declare java.lang.RuntimeException or it's subclasses in throws clause of it's signature, since it is advised to avoid declaring unchecked exceptions in method signature.
+
+ 3
+
+
diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionTest.java
new file mode 100644
index 0000000000..9acdac1f31
--- /dev/null
+++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/rule/design/SignatureDeclareThrowsRuntimeExceptionTest.java
@@ -0,0 +1,11 @@
+/**
+ * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+ */
+
+package net.sourceforge.pmd.lang.java.rule.design;
+
+import net.sourceforge.pmd.testframework.PmdRuleTst;
+
+public class SignatureDeclareThrowsRuntimeExceptionTest extends PmdRuleTst {
+ // no additional unit tests
+}