Patterns
The bug patterns in Codegex are derived from SpotBugs. We select SpotBugs because it (1) is the most well-known and most used static analyzer, and (2) can detect more diverse types of bugs than other tools (e.g., Error Prone, PMD, Infer).
Motivating Study
Static analysis tools rely on bug patterns to detect a potential problem or bug in a given input program. We conducted a study of SpotBugs patterns and divide them into four categories (inter-class, class, method and statement) according to the context scope they use.
Research Questions
RQ1: What is the scope of analysis needed to detect a bug pattern in SpotBugs?
RQ2: What program analysis techniques are important for detecting a bug pattern in SpotBugs?
We provides the link of study table of SpotBugs' 451 patterns (2021/01) here.

Codegex patterns
Number of Implemented Patterns
Project | Number of Patterns |
---|---|
Bad practice (BAD_PRACTICE) | 22 |
Correctness (CORRECTNESS) | 37 |
Malicious code vulnerability (MALICIOUS_CODE) | 1 |
Multithreaded correctness (MT_CORRECTNESS) | 5 |
Performance (PERFORMANCE) | 14 |
Dodgy code (STYLE) | 8 |
Total | 87 |
Supported patterns
Bad practice (BAD_PRACTICE)
- CNT: Rough value of known constant found (CNT_ROUGH_CONSTANT_VALUE)
- UI: Usage of GetResource may be unsafe if class is extended (UI_INHERITANCE_UNSAFE_GETRESOURCE)
- IMSE: Dubious catching of IllegalMonitorStateException (IMSE_DONT_CATCH_IMSE)
- Nm: Use of identifier that is a keyword in later versions of Java (NM_FUTURE_KEYWORD_USED_AS_IDENTIFIER)
- Nm: Use of identifier that is a keyword in later versions of Java (NM_FUTURE_KEYWORD_USED_AS_MEMBER_IDENTIFIER)
- Dm: Method invokes dangerous method runFinalizersOnExit (DM_RUN_FINALIZERS_ON_EXIT)
- FI: Explicit invocation of finalizer (FI_EXPLICIT_INVOCATION)
- ES: Comparison of String objects using == or != (ES_COMPARING_STRINGS_WITH_EQ)
- Nm: Method names should start with a lower case letter (NM_METHOD_NAMING_CONVENTION)
- Nm: Class names shouldn’t shadow simple name of implemented interface (NM_SAME_SIMPLE_NAME_AS_INTERFACE)
- Nm: Class names shouldn’t shadow simple name of superclass (NM_SAME_SIMPLE_NAME_AS_SUPERCLASS)
- Nm: Class names should start with an upper case letter (NM_CLASS_NAMING_CONVENTION)
- Nm: Class is not derived from an Exception, even though it is named as such (NM_CLASS_NOT_EXCEPTION)
- Se: The readResolve method must be declared with a return type of Object. (SE_READ_RESOLVE_MUST_RETURN_OBJECT)
- Se: serialVersionUID isn’t final (SE_NONFINAL_SERIALVERSIONID)
- Se: serialVersionUID isn’t static (SE_NONSTATIC_SERIALVERSIONID)
- Se: serialVersionUID isn’t long (SE_NONLONG_SERIALVERSIONID)
- RC: Suspicious reference comparison of Boolean values (RC_REF_COMPARISON_BAD_PRACTICE_BOOLEAN)
- FS: Format string should use %n rather than n (VA_FORMAT_STRING_USES_NEWLINE)
- DMI: Random object created and used only once (DMI_RANDOM_USED_ONLY_ONCE)
- PZ: Don’t reuse entry objects in iterators (PZ_DONT_REUSE_ENTRY_OBJECTS_IN_ITERATORS)
- DMI: Don’t use removeAll to clear a collection (DMI_USING_REMOVEALL_TO_CLEAR_COLLECTION)
Correctness (CORRECTNESS)
- IL: A collection is added to itself (IL_CONTAINER_ADDED_TO_ITSELF)
- Dm: Useless/vacuous call to EasyMock method (DMI_VACUOUS_CALL_TO_EASYMOCK_METHOD)
- DMI: BigDecimal constructed from double that isn’t represented precisely (DMI_BIGDECIMAL_CONSTRUCTED_FROM_DOUBLE)
- RV: Random value from 0 to 1 is coerced to the integer 0 (RV_01_TO_INT)
- Dm: Incorrect combination of Math.max and Math.min (DM_INVALID_MIN_MAX)
- Nm: Class defines hashcode(); should it be hashCode()? (NM_LCASE_HASHCODE)
- Nm: Class defines tostring(); should it be toString()? (NM_LCASE_TOSTRING)
- Nm: Class defines equal(Object); should it be equals(Object)? (NM_BAD_EQUAL)
- Se: The readResolve method must not be declared as a static method. (SE_READ_RESOLVE_IS_STATIC)
- Se: Method must be private in order for serialization to work (SE_METHOD_MUST_BE_PRIVATE)
- RV: Exception created and dropped rather than thrown (RV_EXCEPTION_NOT_THROWN)
- DMI: Reversed method arguments (DMI_ARGUMENTS_WRONG_ORDER)
- EC: Call to equals(null) (EC_NULL_ARG)
- BIT: Bitwise OR of signed byte value (BIT_IOR_OF_SIGNED_BYTE)
- BIT: Check for sign of bitwise operation involving negative number (BIT_SIGNED_CHECK_HIGH_BIT)
- BIT: Incompatible bit masks (BIT_AND)
- BIT: Check to see if ((…) & 0) == 0 (BIT_AND_ZZ)
- BIT: Incompatible bit masks (BIT_IOR)
- SA: Self assignment of field (SA_FIELD_SELF_ASSIGNMENT)
- SA: Nonsensical self computation involving a field (e.g., x & x) (SA_FIELD_SELF_COMPUTATION)
- SA: Nonsensical self computation involving a variable (e.g., x & x) (SA_LOCAL_SELF_COMPUTATION)
- SA: Self comparison of field with itself (SA_FIELD_SELF_COMPARISON)
- SA: Self comparison of value with itself (SA_LOCAL_SELF_COMPARISON)
- DLS: Useless increment in return statement (DLS_DEAD_LOCAL_INCREMENT_IN_RETURN)
- FE: Doomed test for equality to NaN (FE_TEST_IF_EQUAL_TO_NOT_A_NUMBER)
- BC: Impossible downcast of toArray() result (BC_IMPOSSIBLE_DOWNCAST_OF_TOARRAY)
- RE: “.” or “|” used for regular expression (RE_POSSIBLE_UNINTENDED_PATTERN)
- RE: File.separator used for regular expression (RE_CANT_USE_FILE_SEPARATOR_AS_REGULAR_EXPRESSION)
- DLS: Overwritten increment (DLS_OVERWRITTEN_INCREMENT)
- BSHIFT: Possible bad parsing of shift operation (BSHIFT_WRONG_ADD_PRIORITY)
- IM: Integer multiply of result of integer remainder (IM_MULTIPLYING_RESULT_OF_IREM)
- USELESS_STRING: Invocation of toString on an unnamed array (DMI_INVOKING_TOSTRING_ON_ANONYMOUS_ARRAY)
- DMI: Bad constant value for month (DMI_BAD_MONTH)
- QBA: Method assigns boolean literal in boolean expression (QBA_QUESTIONABLE_BOOLEAN_ASSIGNMENT)
- DMI: Vacuous call to collections (DMI_VACUOUS_SELF_COLLECTION_CALL)
- DMI: D’oh! A nonsensical method invocation (DMI_DOH)
- DMI: Collections should not contain themselves (DMI_COLLECTIONS_SHOULD_NOT_CONTAIN_THEMSELVES)
Malicious code vulnerability (MALICIOUS_CODE)
- FI: Finalizer should be protected, not public (FI_PUBLIC_SHOULD_BE_PROTECTED)
Multithreaded correctness (MT_CORRECTNESS)
- STCAL: Static Calendar field (STCAL_STATIC_CALENDAR_INSTANCE)
- STCAL: Static DateFormat (STCAL_STATIC_SIMPLE_DATE_FORMAT_INSTANCE)
- VO: A volatile reference to an array doesn’t treat the array elements as volatile (VO_VOLATILE_REFERENCE_TO_ARRAY)
- WL: Synchronization on getClass rather than class literal (WL_USING_GETCLASS_RATHER_THAN_CLASS_LITERAL)
- No: Using notify() rather than notifyAll() (NO_NOTIFY_NOT_NOTIFYALL)
Performance (PERFORMANCE)
- Dm: Maps and sets of URLs can be performance hogs (DMI_COLLECTION_OF_URLS)
- Dm: Method invokes inefficient new String(String) constructor (DM_STRING_CTOR)
- Dm: Method invokes inefficient new String() constructor (DM_STRING_VOID_CTOR)
- Dm: Method invokes inefficient Boolean constructor; use Boolean.valueOf(…) instead (DM_BOOLEAN_CTOR)
- Bx: Method invokes inefficient Number constructor; use static valueOf instead (DM_NUMBER_CTOR)
- Bx: Method invokes inefficient floating-point Number constructor; use static valueOf instead (DM_FP_NUMBER_CTOR)
- Bx: Method allocates a boxed primitive just to call toString (DM_BOXED_PRIMITIVE_TOSTRING)
- Bx: Boxing/unboxing to parse a primitive (DM_BOXED_PRIMITIVE_FOR_PARSING)
- Bx: Boxing a primitive to compare (DM_BOXED_PRIMITIVE_FOR_COMPARE)
- Bx: Primitive value is boxed then unboxed to perform primitive coercion (BX_BOXING_IMMEDIATELY_UNBOXED_TO_PERFORM_COERCION)
- Dm: Method allocates an object, only to get the class object (DM_NEW_FOR_GETCLASS)
- Dm: Use the nextInt method of Random rather than nextDouble to generate a random integer (DM_NEXTINT_VIA_NEXTDOUBLE)
- IIO: Inefficient use of String.indexOf(String) (IIO_INEFFICIENT_INDEX_OF)
- IIO: Inefficient use of String.lastIndexOf(String) (IIO_INEFFICIENT_LAST_INDEX_OF)
Dodgy code (STYLE)
- NP: Immediate dereference of the result of readLine() (NP_IMMEDIATE_DEREFERENCE_OF_READLINE)
- RV: Method discards result of readLine after checking if it is non-null (RV_DONT_JUST_NULL_CHECK_READLINE)
- UCF: Useless control flow to next line (UCF_USELESS_CONTROL_FLOW_NEXT_LINE)
- SA: Self assignment of local variable (SA_LOCAL_SELF_ASSIGNMENT)
- SA: Double assignment of local variable (SA_LOCAL_DOUBLE_ASSIGNMENT)
- SA: Double assignment of field (SA_FIELD_DOUBLE_ASSIGNMENT)
- DMI: Code contains a hard coded reference to an absolute pathname (DMI_HARDCODED_ABSOLUTE_FILENAME)
- DMI: Invocation of substring(0), which returns the original value (DMI_USELESS_SUBSTRING)