diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/AbstractTypeAwareCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/AbstractTypeAwareCheck.java
index bff10abc3..b29487e2a 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/AbstractTypeAwareCheck.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/AbstractTypeAwareCheck.java
@@ -184,6 +184,27 @@ public abstract class AbstractTypeAwareCheck
}
}
+ /**
+ * Tries to load class. Logs error if unable.
+ * @param aIdent name of class which we try to load.
+ * @return Class for a ident.
+ */
+ protected final Class tryLoadClass(FullIdent aIdent)
+ {
+ Class clazz = resolveClass(aIdent.getText());
+ if (clazz == null) {
+ logLoadError(aIdent);
+ }
+ return clazz;
+ }
+
+ /**
+ * Logs error if unable to load class information.
+ * Abstract, should be overrided in subclasses.
+ * @param aIdent class name for which we can no load class.
+ */
+ protected abstract void logLoadError(FullIdent aIdent);
+
/**
* Collects the details of a package.
* @param aAST node containing the package details
@@ -210,7 +231,7 @@ public abstract class AbstractTypeAwareCheck
* Contains class's FullIdent
* and Class object if we can load it.
*/
- protected static class ClassInfo
+ protected class ClassInfo
{
/** FullIdent associated with this class. */
private FullIdent mName;
@@ -264,6 +285,9 @@ public abstract class AbstractTypeAwareCheck
/** @return Class associated with an object. */
public final Class getClazz()
{
+ if (isLoadable() && mClass == null) {
+ setClazz(AbstractTypeAwareCheck.this.tryLoadClass(getName()));
+ }
return mClass;
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheck.java
index 63663d754..566a56fb3 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheck.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheck.java
@@ -111,6 +111,16 @@ public class RedundantThrowsCheck
}
}
+ /**
+ * Logs error if unable to load class information.
+ * @param aIdent class name for which we can no load class.
+ */
+ protected final void logLoadError(FullIdent aIdent)
+ {
+ log(aIdent.getLineNo(), aIdent.getColumnNo(),
+ "redundant.throws.classInfo", aIdent.getText());
+ }
+
/**
* Checks if an exception is already know (list of known
* exceptions contains it or its superclass) and it's not
@@ -125,19 +135,11 @@ public class RedundantThrowsCheck
*/
private void checkException(FullIdent aExc, List aKnownExcs)
{
- // Let's trye to load class.
- Class excClass = null;
-
- if (!mAllowUnchecked || !mAllowSubclasses) {
- excClass = resolveClass(aExc.getText());
- if (excClass == null) {
- log(aExc.getLineNo(), aExc.getColumnNo(),
- "redundant.throws.classInfo", aExc.getText());
- }
- }
+ // Let's try to load class.
+ ClassInfo newClassInfo = new ClassInfo(aExc);
if (!mAllowUnchecked) {
- if (isUnchecked(excClass)) {
+ if (isUnchecked(newClassInfo.getClazz())) {
log(aExc.getLineNo(), aExc.getColumnNo(),
"redundant.throws.unchecked", aExc.getText());
}
@@ -154,13 +156,13 @@ public class RedundantThrowsCheck
"redundant.throws.duplicate", aExc.getText());
}
else if (!mAllowSubclasses) {
- if (isSubclass(ci.getClazz(), excClass)) {
+ if (isSubclass(ci.getClazz(), newClassInfo.getClazz())) {
known.remove();
log(fi.getLineNo(), fi.getColumnNo(),
"redundant.throws.subclass",
fi.getText(), aExc.getText());
}
- else if (isSubclass(excClass, ci.getClazz())) {
+ else if (isSubclass(newClassInfo.getClazz(), ci.getClazz())) {
shouldAdd = false;
log(aExc.getLineNo(), aExc.getColumnNo(),
"redundant.throws.subclass",
@@ -170,7 +172,7 @@ public class RedundantThrowsCheck
}
if (shouldAdd) {
- aKnownExcs.add(new ClassInfo(aExc, excClass));
+ aKnownExcs.add(newClassInfo);
}
}
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocMethodCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocMethodCheck.java
index 400d08b2a..c5f6b9217 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocMethodCheck.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/javadoc/JavadocMethodCheck.java
@@ -572,15 +572,7 @@ public class JavadocMethodCheck
final String documentedEx = tag.getArg1();
boolean found = foundThrows.contains(documentedEx);
Class documentedClass = null;
- if (!found
- && (mAllowThrowsTagsForSubclasses || mAllowUndeclaredRTE))
- {
- documentedClass = resolveClass(documentedEx);
- if (documentedClass == null) {
- log(tag.getLineNo(), "javadoc.classInfo",
- "@throws", documentedEx);
- }
- }
+ boolean classLoaded = false;
final ListIterator throwIt = aThrows.listIterator();
while (!found && throwIt.hasNext()) {
@@ -592,19 +584,11 @@ public class JavadocMethodCheck
ei.setFound();
foundThrows.add(documentedEx);
}
- else if (mAllowThrowsTagsForSubclasses
- && documentedClass != null)
- {
- if (ei.isLoadable() && ei.getClazz() == null) {
- // if the class is not loaded yet.
- // try to load it.
- ei.setClazz(resolveClass(declaredEx));
- if (!ei.isLoadable()) {
- log(fi.getLineNo(), "javadoc.classInfo",
- "@throws", declaredEx);
- }
+ else if (mAllowThrowsTagsForSubclasses) {
+ if (!classLoaded) {
+ documentedClass = loadClassForTag(tag);
+ classLoaded = true;
}
-
found = isSubclass(documentedClass, ei.getClazz());
if (found) {
ei.setFound();
@@ -615,7 +599,11 @@ public class JavadocMethodCheck
// Handle extra JavadocTag.
if (!found) {
boolean reqd = true;
- if (mAllowUndeclaredRTE && documentedClass != null) {
+ if (mAllowUndeclaredRTE) {
+ if (!classLoaded) {
+ documentedClass = loadClassForTag(tag);
+ classLoaded = true;
+ }
reqd = !isUnchecked(documentedClass);
}
@@ -641,8 +629,33 @@ public class JavadocMethodCheck
}
}
+ /**
+ * Tries to load class for throws tag. Logs error if unable.
+ * @param aTag name of class which we try to load.
+ * @return Class for the tag.
+ */
+ private Class loadClassForTag(JavadocTag aTag)
+ {
+ Class clazz = resolveClass(aTag.getArg1());
+ if (clazz == null) {
+ log(aTag.getLineNo(), "javadoc.classInfo",
+ "@throws", aTag.getArg1());
+ }
+ return clazz;
+ }
+
+ /**
+ * Logs error if unable to load class information.
+ * @param aIdent class name for which we can no load class.
+ */
+ protected final void logLoadError(FullIdent aIdent)
+ {
+ log(aIdent.getLineNo(), "javadoc.classInfo", "@throws",
+ aIdent.getText());
+ }
+
/** Stores useful information about declared exception. */
- static class ExceptionInfo extends ClassInfo
+ class ExceptionInfo extends ClassInfo
{
/** does the exception have throws tag associated with. */
private boolean mFound;
diff --git a/src/testinputs/com/puppycrawl/tools/checkstyle/InputTags.java b/src/testinputs/com/puppycrawl/tools/checkstyle/InputTags.java
index 5d79ff2f9..4bd8ea74e 100644
--- a/src/testinputs/com/puppycrawl/tools/checkstyle/InputTags.java
+++ b/src/testinputs/com/puppycrawl/tools/checkstyle/InputTags.java
@@ -239,4 +239,11 @@ class InputTags
throws IOException
{
}
+
+ /**
+ * @exception WrongException exception w/o class info but matched by name
+ */
+ void method23() throws WrongException
+ {
+ }
}
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheckTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheckTest.java
index 943c1f69d..0302cf135 100644
--- a/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheckTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/coding/RedundantThrowsCheckTest.java
@@ -31,7 +31,6 @@ public class RedundantThrowsCheckTest
final String[] expected = {
"7:37: Redundant throws: 'java.io.FileNotFoundException' is subclass of 'java.io.IOException'.",
"19:29: Redundant throws: 'java.io.IOException' listed more then one time.",
- "25:16: Unable to get class information for WrongException.",
"35:27: Unable to get class information for WrongException.",
"39:27: Redundant throws: 'NullPointerException' is subclass of 'RuntimeException'.",
};