Exception Fact Sheet for "java_regexp"

The goal of an Exception Fact Sheet is to reveal the design of exception handling in an application.

--Maxence, Martin

For feedback, please contact Martin

Table of contents

Basic Statistics

Number of Classes 93
Number of Domain Exception Types (Thrown or Caught) 1
Number of Domain Checked Exception Types 0
Number of Domain Runtime Exception Types 1
Number of Domain Unknown Exception Types 0
nTh = Number of Throw 43
nTh = Number of Throw in Catch 2
Number of Catch-Rethrow (may not be correct) 0
nC = Number of Catch 2
nCTh = Number of Catch with Throw 2
Number of Empty Catch (really Empty) 0
Number of Empty Catch (with comments) 0
Number of Empty Catch 0
nM = Number of Methods 307
nbFunctionWithCatch = Number of Methods with Catch 2 / 307
nbFunctionWithThrow = Number of Methods with Throw 27 / 307
nbFunctionWithThrowS = Number of Methods with ThrowS 1 / 307
nbFunctionTransmitting = Number of Methods with "Throws" but NO catch, NO throw (only transmitting) 1 / 307
P1 = nCTh / nC 100% (1)
P2 = nMC / nM 0.7% (0.007)
P3 = nbFunctionWithThrow / nbFunction 8.8% (0.088)
P4 = nbFunctionTransmitting / nbFunction 0.3% (0.003)
P5 = nbThrowInCatch / nbThrow 4.7% (0.047)
R2 = nCatch / nThrow 0.047
A1 = Number of Caught Exception Types From External Libraries 2
A2 = Number of Reused Exception Types From External Libraries (thrown from application code) 5

W1 is a rough estimation of the richness of the exception model. It does not take into account the inheritance relationships between domain exceptions.

Proportion P1 measures the overall exception flow. According to our experience, it varies from 5% to 70%. Early-catch design generally yields a low P1, libraries that must warn clients about errors (e.g. databases) generally have a high P1.

Proportion P2 measures the dispersion of catch blocks in the application. According to our experience, it varies from 2% to 15%. A small P2 indicates a rather centralized management of errors.

R1 shows how many exceptions types from libraries (incl. JDK) are thrown from application code. For instance, IllegalArgumentException comes from the JDK but is used in many applications.

A1 measures the awareness of the application to library exceptions. A high value of A1 means either that the application is polluted with checked exceptions or that it is able to apply specific recovery depending on the library exception.

Exception Hierachy

Exception Map

Each exception that is used at least once in the project is a dot. A orange dot represents a domain exception that is defined in the application. A blue dot exception is defined in the JDK or in a library. The x-axis represents the number of times an exception is caught, the y-axis the number of times an exception is thrown.

Exceptions With State

State means fields. Number of exceptions with state: 1
PatternSyntaxException
              package java.util.regex;public class PatternSyntaxException
    extends IllegalArgumentException
{

    private final String desc;
    private final String pattern;
    private final int index;

    /**
     * Constructs a new instance of this class.
     *
     * @param  desc
     *         A description of the error
     *
     * @param  regex
     *         The erroneous pattern
     *
     * @param  index
     *         The approximate index in the pattern of the error,
     *         or <tt>-1</tt> if the index is not known
     */
    public PatternSyntaxException(String desc, String regex, int index) {
	this.desc = desc;
	this.pattern = regex;
	this.index = index;
    }

    /**
     * Retrieves the error index.
     *
     * @return  The approximate index in the pattern of the error,
     *         or <tt>-1</tt> if the index is not known
     */
    public int getIndex() {
	return index;
    }

    /**
     * Retrieves the description of the error.
     *
     * @return  The description of the error
     */
    public String getDescription() {
	return desc;
    }

    /**
     * Retrieves the erroneous regular-expression pattern.
     *
     * @return  The erroneous pattern
     */
    public String getPattern() {
	return pattern;
    }

    private static final String nl =
	java.security.AccessController
	    .doPrivileged(new GetPropertyAction("line.separator"));

    /**
     * Returns a multi-line string containing the description of the syntax
     * error and its index, the erroneous regular-expression pattern, and a
     * visual indication of the error index within the pattern.
     *
     * @return  The full detail message
     */
    public String getMessage() {
        StringBuffer sb = new StringBuffer();
        sb.append(desc);
	if (index >= 0) {
	    sb.append(" near index ");
	    sb.append(index);
	}
        sb.append(nl);
        sb.append(pattern);
	if (index >= 0) {
	    sb.append(nl);
	    for (int i = 0; i < index; i++) sb.append(' ');
	    sb.append('^');
	}
        return sb.toString();
    }

}
            

Thrown Exceptions Summary

A (Domain) exception is defined in the application. A (Lib) exception is defined in the JDK or in a library. An exception can be thrown, thrown from within a catch, or declared in the signature of a method (usually for checked exceptions). Hovering over a number triggers showing code snippets from the application code.

Type Exception Thrown Thrown
from Catch
Declared
- Unknown 26
              
//in java_regexp/Pattern.java
throw error("Unclosed character class");

              
//in java_regexp/Pattern.java
throw error("Unmatched closing ')'");

              
//in java_regexp/Pattern.java
throw error("Unexpected internal error");

              
//in java_regexp/Pattern.java
throw error(s);

              
//in java_regexp/Pattern.java
throw error("Dangling meta character '" + ((char)ch) + "'");

              
//in java_regexp/Pattern.java
throw error("Illegal/unsupported escape sequence");

              
//in java_regexp/Pattern.java
throw error("Bad class syntax");

              
//in java_regexp/Pattern.java
throw error("Unclosed character class");

              
//in java_regexp/Pattern.java
throw error("Illegal character range");

              
//in java_regexp/Pattern.java
throw error("Unexpected character '"+((char)ch)+"'");

              
//in java_regexp/Pattern.java
throw error("Unclosed character family");

              
//in java_regexp/Pattern.java
throw error("Empty character family");

              
//in java_regexp/Pattern.java
throw error("Unknown character block name {" + name + "}");

              
//in java_regexp/Pattern.java
throw error("Unknown character property name {" + name + "}");

              
//in java_regexp/Pattern.java
throw error("Look-behind group does not have "
				+ "an obvious maximum length");

              
//in java_regexp/Pattern.java
throw error("Unknown look-behind group");

              
//in java_regexp/Pattern.java
throw error("Unknown group type");

              
//in java_regexp/Pattern.java
throw error("Unknown inline modifier");

              
//in java_regexp/Pattern.java
throw error("Internal logic error");

              
//in java_regexp/Pattern.java
throw error("Unclosed counted closure");

              
//in java_regexp/Pattern.java
throw error("Illegal repetition range");

              
//in java_regexp/Pattern.java
throw error("Illegal repetition");

              
//in java_regexp/Pattern.java
throw error("Illegal control escape sequence");

              
//in java_regexp/Pattern.java
throw error("Illegal octal escape sequence");

              
//in java_regexp/Pattern.java
throw error("Illegal hexadecimal escape sequence");

              
//in java_regexp/Pattern.java
throw error("Illegal Unicode escape sequence");

            
- -
- Builder 26
              
// in java_regexp/Pattern.java
throw error("Unclosed character class");

              
// in java_regexp/Pattern.java
throw error("Unmatched closing ')'");

              
// in java_regexp/Pattern.java
throw error("Unexpected internal error");

              
// in java_regexp/Pattern.java
throw error(s);

              
// in java_regexp/Pattern.java
throw error("Dangling meta character '" + ((char)ch) + "'");

              
// in java_regexp/Pattern.java
throw error("Illegal/unsupported escape sequence");

              
// in java_regexp/Pattern.java
throw error("Bad class syntax");

              
// in java_regexp/Pattern.java
throw error("Unclosed character class");

              
// in java_regexp/Pattern.java
throw error("Illegal character range");

              
// in java_regexp/Pattern.java
throw error("Unexpected character '"+((char)ch)+"'");

              
// in java_regexp/Pattern.java
throw error("Unclosed character family");

              
// in java_regexp/Pattern.java
throw error("Empty character family");

              
// in java_regexp/Pattern.java
throw error("Unknown character block name {" + name + "}");

              
// in java_regexp/Pattern.java
throw error("Unknown character property name {" + name + "}");

              
// in java_regexp/Pattern.java
throw error("Look-behind group does not have "
				+ "an obvious maximum length");

              
// in java_regexp/Pattern.java
throw error("Unknown look-behind group");

              
// in java_regexp/Pattern.java
throw error("Unknown group type");

              
// in java_regexp/Pattern.java
throw error("Unknown inline modifier");

              
// in java_regexp/Pattern.java
throw error("Internal logic error");

              
// in java_regexp/Pattern.java
throw error("Unclosed counted closure");

              
// in java_regexp/Pattern.java
throw error("Illegal repetition range");

              
// in java_regexp/Pattern.java
throw error("Illegal repetition");

              
// in java_regexp/Pattern.java
throw error("Illegal control escape sequence");

              
// in java_regexp/Pattern.java
throw error("Illegal octal escape sequence");

              
// in java_regexp/Pattern.java
throw error("Illegal hexadecimal escape sequence");

              
// in java_regexp/Pattern.java
throw error("Illegal Unicode escape sequence");

            
- -
- Variable 0 - -
(Lib) IndexOutOfBoundsException 7
              
// in java_regexp/Matcher.java
public int start(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2]; }
// in java_regexp/Matcher.java
public int end(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2 + 1]; }
// in java_regexp/Matcher.java
public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); }
// in java_regexp/Matcher.java
public boolean find(int start) { int limit = getTextLength(); if ((start < 0) || (start > limit)) throw new IndexOutOfBoundsException("Illegal start index"); reset(); return search(start); }
// in java_regexp/Matcher.java
public Matcher region(int start, int end) { if ((start < 0) || (start > getTextLength())) throw new IndexOutOfBoundsException("start"); if ((end < 0) || (end > getTextLength())) throw new IndexOutOfBoundsException("end"); if (start > end) throw new IndexOutOfBoundsException("start > end"); reset(); from = start; to = end; return this; }
0 0
(Lib) IllegalStateException 6
              
// in java_regexp/Matcher.java
public int start() { if (first < 0) throw new IllegalStateException("No match available"); return first; }
// in java_regexp/Matcher.java
public int start(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2]; }
// in java_regexp/Matcher.java
public int end() { if (first < 0) throw new IllegalStateException("No match available"); return last; }
// in java_regexp/Matcher.java
public int end(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2 + 1]; }
// in java_regexp/Matcher.java
public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); }
// in java_regexp/Matcher.java
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; String s = replacement; StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // The first number is always a group int refNum = (int)replacement.charAt(cursor) - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } // Append group if (group(refNum) != null) result.append(group(refNum)); } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(getSubSequence(lastAppendPosition, first)); // Append the match substitution sb.append(result.toString()); lastAppendPosition = last; return this; }
0 0
(Lib) IllegalArgumentException 2
              
// in java_regexp/Matcher.java
public Matcher usePattern(Pattern newPattern) { if (newPattern == null) throw new IllegalArgumentException("Pattern cannot be null"); parentPattern = newPattern; // Reallocate state storage int parentGroupCount = Math.max(newPattern.capturingGroupCount, 10); groups = new int[parentGroupCount * 2]; locals = new int[newPattern.localCount]; for (int i = 0; i < groups.length; i++) groups[i] = -1; for (int i = 0; i < locals.length; i++) locals[i] = -1; return this; }
// in java_regexp/Matcher.java
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; String s = replacement; StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // The first number is always a group int refNum = (int)replacement.charAt(cursor) - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } // Append group if (group(refNum) != null) result.append(group(refNum)); } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(getSubSequence(lastAppendPosition, first)); // Append the match substitution sb.append(result.toString()); lastAppendPosition = last; return this; }
0 0
(Lib) AssertionError 1
              
// in java_regexp/Pattern.java
public CloneableProperty clone() { try { return (CloneableProperty) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } }
1
              
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
0
(Lib) NullPointerException 1
              
// in java_regexp/Matcher.java
public String replaceFirst(String replacement) { if (replacement == null) throw new NullPointerException("replacement"); StringBuffer sb = new StringBuffer(); reset(); if (find()) appendReplacement(sb, replacement); appendTail(sb); return sb.toString(); }
0 0
Explicit thrown (throw new...): 17/43
Explicit thrown ratio: 39.5%
Builder thrown ratio: 60.5%
Variable thrown ratio: 0%
Checked Runtime Total
Domain 0 0 0
Lib 0 9 9
Total 0 9

Caught Exceptions Summary

A (Domain) exception is defined in the application. A (Lib) exception is defined in the JDK or in a library. An exception can be caught, and it happens that the catch block contains a throw (e.g. for wrapping a low-level exception). Hovering over a number triggers showing code snippets from the application code.

Type Exception Caught
(directly)
Caught
with Thrown
(Lib) CloneNotSupportedException 1
            
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
1
            
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
(Lib) IllegalArgumentException 1
            
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }
1
            
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }

Exception Recast Summary

There is a common practice of throwing exceptions from within a catch block (e.g. for wrapping a low-level exception). The following table summarizes the usage of this practice in the application. The last column gives the number of times it happens for a pair of exceptions. The graph below the table graphically renders the same information. For a given node, its color represents its origin (blue means library exception, orange means domain exception); the left-most number is the number of times it is thrown, the right-most is the number of times it is caught.

Catch Throw
(Lib) IllegalArgumentException
Unknown
1
                    
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }
(Lib) CloneNotSupportedException
(Lib) AssertionError
1
                    
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }

Caught / Thrown Exception

Not all exceptions are thrown AND caught in the same project. The following table gives the exceptions types with respect to this. The lower left hand side sell lists all exceptions thrown but not caught (prevalent for libraries), the upper right-hand side lists all exceptions caught but not thrown (usually coming from external dependencies).

Thrown Not Thrown
Caught
Type Name
(Lib) IllegalArgumentException
Type Name
(Lib) CloneNotSupportedException
Not caught
Type Name
(Lib) AssertionError
(Lib) IllegalStateException
(Lib) IndexOutOfBoundsException
(Lib) NullPointerException

Methods called in Catch and Finally Blocks

The following shows the methods that are called inside catch blocks (first column) and finally blocks (second column). For each method, we give the number of times it is called in a catch block (second sub-column), and the total number of calls (third sub-column). If the method name is red, it means that it is only called from catch/finally blocks. Hovering over a number triggers showing code snippets from the application code.

Catch Finally
Method Nbr Nbr total
error 1
                  
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }
26
Method Nbr Nbr total

Reference Table

This table concatenates the results of the previous tables.

Checked/Runtime Type Exception Thrown Thrown from Catch Declared Caught directly Caught
with Thrown
Caught
with Thrown Runtime
unknown (Lib) AssertionError 1
            
// in java_regexp/Pattern.java
public CloneableProperty clone() { try { return (CloneableProperty) super.clone(); } catch (CloneNotSupportedException e) { throw new AssertionError(e); } }
1
            
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
0 0 0 0
unknown (Lib) CloneNotSupportedException 0 0 0 1
            
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
1
            
// in java_regexp/Pattern.java
catch (CloneNotSupportedException e) { throw new AssertionError(e); }
0
runtime (Lib) IllegalArgumentException 2
            
// in java_regexp/Matcher.java
public Matcher usePattern(Pattern newPattern) { if (newPattern == null) throw new IllegalArgumentException("Pattern cannot be null"); parentPattern = newPattern; // Reallocate state storage int parentGroupCount = Math.max(newPattern.capturingGroupCount, 10); groups = new int[parentGroupCount * 2]; locals = new int[newPattern.localCount]; for (int i = 0; i < groups.length; i++) groups[i] = -1; for (int i = 0; i < locals.length; i++) locals[i] = -1; return this; }
// in java_regexp/Matcher.java
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; String s = replacement; StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // The first number is always a group int refNum = (int)replacement.charAt(cursor) - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } // Append group if (group(refNum) != null) result.append(group(refNum)); } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(getSubSequence(lastAppendPosition, first)); // Append the match substitution sb.append(result.toString()); lastAppendPosition = last; return this; }
0 0 1
            
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }
1
            
// in java_regexp/Pattern.java
catch (IllegalArgumentException iae) { throw error("Unknown character block name {" + name + "}"); }
0
runtime (Lib) IllegalStateException 6
            
// in java_regexp/Matcher.java
public int start() { if (first < 0) throw new IllegalStateException("No match available"); return first; }
// in java_regexp/Matcher.java
public int start(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2]; }
// in java_regexp/Matcher.java
public int end() { if (first < 0) throw new IllegalStateException("No match available"); return last; }
// in java_regexp/Matcher.java
public int end(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2 + 1]; }
// in java_regexp/Matcher.java
public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); }
// in java_regexp/Matcher.java
public Matcher appendReplacement(StringBuffer sb, String replacement) { // If no match, return error if (first < 0) throw new IllegalStateException("No match available"); // Process substitution string to replace group references with groups int cursor = 0; String s = replacement; StringBuffer result = new StringBuffer(); while (cursor < replacement.length()) { char nextChar = replacement.charAt(cursor); if (nextChar == '\\') { cursor++; nextChar = replacement.charAt(cursor); result.append(nextChar); cursor++; } else if (nextChar == '$') { // Skip past $ cursor++; // The first number is always a group int refNum = (int)replacement.charAt(cursor) - '0'; if ((refNum < 0)||(refNum > 9)) throw new IllegalArgumentException( "Illegal group reference"); cursor++; // Capture the largest legal group string boolean done = false; while (!done) { if (cursor >= replacement.length()) { break; } int nextDigit = replacement.charAt(cursor) - '0'; if ((nextDigit < 0)||(nextDigit > 9)) { // not a number break; } int newRefNum = (refNum * 10) + nextDigit; if (groupCount() < newRefNum) { done = true; } else { refNum = newRefNum; cursor++; } } // Append group if (group(refNum) != null) result.append(group(refNum)); } else { result.append(nextChar); cursor++; } } // Append the intervening text sb.append(getSubSequence(lastAppendPosition, first)); // Append the match substitution sb.append(result.toString()); lastAppendPosition = last; return this; }
0 0 0 0 0
unknown (Lib) IndexOutOfBoundsException 7
            
// in java_regexp/Matcher.java
public int start(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2]; }
// in java_regexp/Matcher.java
public int end(int group) { if (first < 0) throw new IllegalStateException("No match available"); if (group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); return groups[group * 2 + 1]; }
// in java_regexp/Matcher.java
public String group(int group) { if (first < 0) throw new IllegalStateException("No match found"); if (group < 0 || group > groupCount()) throw new IndexOutOfBoundsException("No group " + group); if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null; return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString(); }
// in java_regexp/Matcher.java
public boolean find(int start) { int limit = getTextLength(); if ((start < 0) || (start > limit)) throw new IndexOutOfBoundsException("Illegal start index"); reset(); return search(start); }
// in java_regexp/Matcher.java
public Matcher region(int start, int end) { if ((start < 0) || (start > getTextLength())) throw new IndexOutOfBoundsException("start"); if ((end < 0) || (end > getTextLength())) throw new IndexOutOfBoundsException("end"); if (start > end) throw new IndexOutOfBoundsException("start > end"); reset(); from = start; to = end; return this; }
0 0 0 0 0
runtime (Lib) NullPointerException 1
            
// in java_regexp/Matcher.java
public String replaceFirst(String replacement) { if (replacement == null) throw new NullPointerException("replacement"); StringBuffer sb = new StringBuffer(); reset(); if (find()) appendReplacement(sb, replacement); appendTail(sb); return sb.toString(); }
0 0 0 0 0
runtime (Domain) PatternSyntaxException
public class PatternSyntaxException
    extends IllegalArgumentException
{

    private final String desc;
    private final String pattern;
    private final int index;

    /**
     * Constructs a new instance of this class.
     *
     * @param  desc
     *         A description of the error
     *
     * @param  regex
     *         The erroneous pattern
     *
     * @param  index
     *         The approximate index in the pattern of the error,
     *         or <tt>-1</tt> if the index is not known
     */
    public PatternSyntaxException(String desc, String regex, int index) {
	this.desc = desc;
	this.pattern = regex;
	this.index = index;
    }

    /**
     * Retrieves the error index.
     *
     * @return  The approximate index in the pattern of the error,
     *         or <tt>-1</tt> if the index is not known
     */
    public int getIndex() {
	return index;
    }

    /**
     * Retrieves the description of the error.
     *
     * @return  The description of the error
     */
    public String getDescription() {
	return desc;
    }

    /**
     * Retrieves the erroneous regular-expression pattern.
     *
     * @return  The erroneous pattern
     */
    public String getPattern() {
	return pattern;
    }

    private static final String nl =
	java.security.AccessController
	    .doPrivileged(new GetPropertyAction("line.separator"));

    /**
     * Returns a multi-line string containing the description of the syntax
     * error and its index, the erroneous regular-expression pattern, and a
     * visual indication of the error index within the pattern.
     *
     * @return  The full detail message
     */
    public String getMessage() {
        StringBuffer sb = new StringBuffer();
        sb.append(desc);
	if (index >= 0) {
	    sb.append(" near index ");
	    sb.append(index);
	}
        sb.append(nl);
        sb.append(pattern);
	if (index >= 0) {
	    sb.append(nl);
	    for (int i = 0; i < index; i++) sb.append(' ');
	    sb.append('^');
	}
        return sb.toString();
    }

}
0 0 0 0 0 0

Miscellanous Metrics

nF = Number of Finally 2
nF = Number of Try-Finally (without catch) 2
Number of Methods with Finally (nMF) 2 / 307 (0.7%)
Number of Finally with a Continue 0
Number of Finally with a Return 0
Number of Finally with a Throw 0
Number of Finally with a Break 0
Number of different exception types thrown 5
Number of Domain exception types thrown 0
Number of different exception types caught 2
Number of Domain exception types caught 0
Number of exception declarations in signatures 2
Number of different exceptions types declared in method signatures 2
Number of library exceptions types declared in method signatures 2
Number of Domain exceptions types declared in method signatures 0
Number of Catch with a continue 0
Number of Catch with a return 0
Number of Catch with a Break 0
nbIf = Number of If 410
nbFor = Number of For 62
Number of Method with an if 117 / 307
Number of Methods with a for 49 / 307
Number of Method starting with a try 1 / 307 (0.3%)
Number of Expressions 4071
Number of Expressions in try 23 (0.6%)