Class ExceptionSoftening

  • All Implemented Interfaces:
    edu.umd.cs.findbugs.Detector, edu.umd.cs.findbugs.Priorities, edu.umd.cs.findbugs.visitclass.Constants2, org.apache.bcel.classfile.Visitor, org.apache.bcel.Constants

    public class ExceptionSoftening
    extends edu.umd.cs.findbugs.BytecodeScanningDetector
    looks for methods that catch checked exceptions, and throw unchecked exceptions in their place. There are several levels of concern. Least important are methods constrained by interface or super class contracts not to throw checked exceptions but appear owned by the same author. Next are methods constrained by interface or super class contracts and throw other types of checked exceptions. Lastly are method not constrained by any interface or superclass contract.
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  ExceptionSoftening.CatchInfo
      holds information about a catch block the start and end pcs, as well as the exception signature.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private edu.umd.cs.findbugs.BugReporter bugReporter  
      private int catchFalseReturnPC  
      private java.util.Map<java.lang.Integer,​org.apache.bcel.classfile.CodeException> catchHandlerPCs  
      private java.util.List<ExceptionSoftening.CatchInfo> catchInfos  
      private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> constrainingInfo  
      private boolean hasValidFalseReturn  
      private boolean isBooleanMethod  
      private org.apache.bcel.classfile.LocalVariableTable lvt  
      private org.apache.bcel.classfile.JavaClass runtimeClass  
      private edu.umd.cs.findbugs.OpcodeStack stack  
      • Fields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode

        codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINT
      • Fields inherited from interface org.apache.bcel.Constants

        AALOAD, AASTORE, ACC_ABSTRACT, ACC_ANNOTATION, ACC_BRIDGE, ACC_ENUM, ACC_FINAL, ACC_INTERFACE, ACC_NATIVE, ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC, ACC_STATIC, ACC_STRICT, ACC_SUPER, ACC_SYNCHRONIZED, ACC_SYNTHETIC, ACC_SYPER, ACC_TRANSIENT, ACC_VARARGS, ACC_VOLATILE, ACCESS_NAMES, ACONST_NULL, ALOAD, ALOAD_0, ALOAD_1, ALOAD_2, ALOAD_3, ANEWARRAY, ANEWARRAY_QUICK, APPEND_FRAME, APPEND_FRAME_MAX, ARETURN, ARRAYLENGTH, ASTORE, ASTORE_0, ASTORE_1, ASTORE_2, ASTORE_3, ATHROW, ATTR_ANNOTATION_DEFAULT, ATTR_CODE, ATTR_CONSTANT_VALUE, ATTR_DEPRECATED, ATTR_ENCLOSING_METHOD, ATTR_EXCEPTIONS, ATTR_INNER_CLASSES, ATTR_LINE_NUMBER_TABLE, ATTR_LOCAL_VARIABLE_TABLE, ATTR_LOCAL_VARIABLE_TYPE_TABLE, ATTR_PMG, ATTR_RUNTIME_VISIBLE_ANNOTATIONS, ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, ATTR_RUNTIMEIN_VISIBLE_ANNOTATIONS, ATTR_RUNTIMEIN_VISIBLE_PARAMETER_ANNOTATIONS, ATTR_SIGNATURE, ATTR_SOURCE_FILE, ATTR_STACK_MAP, ATTR_STACK_MAP_TABLE, ATTR_SYNTHETIC, ATTR_UNKNOWN, ATTRIBUTE_NAMES, BALOAD, BASTORE, BIPUSH, BREAKPOINT, CALOAD, CASTORE, CHECKCAST, CHECKCAST_QUICK, CHOP_FRAME, CHOP_FRAME_MAX, CLASS_TYPE_NAMES, CONSTANT_Class, CONSTANT_Double, CONSTANT_Fieldref, CONSTANT_Float, CONSTANT_Integer, CONSTANT_InterfaceMethodref, CONSTANT_InvokeDynamic, CONSTANT_Long, CONSTANT_MethodHandle, CONSTANT_Methodref, CONSTANT_MethodType, CONSTANT_NameAndType, CONSTANT_NAMES, CONSTANT_String, CONSTANT_Utf8, CONSTRUCTOR_NAME, CONSUME_STACK, D2F, D2I, D2L, DADD, DALOAD, DASTORE, DCMPG, DCMPL, DCONST_0, DCONST_1, DDIV, DLOAD, DLOAD_0, DLOAD_1, DLOAD_2, DLOAD_3, DMUL, DNEG, DREM, DRETURN, DSTORE, DSTORE_0, DSTORE_1, DSTORE_2, DSTORE_3, DSUB, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, F2D, F2I, F2L, FADD, FALOAD, FASTORE, FCMPG, FCMPL, FCONST_0, FCONST_1, FCONST_2, FDIV, FLOAD, FLOAD_0, FLOAD_1, FLOAD_2, FLOAD_3, FMUL, FNEG, FREM, FRETURN, FSTORE, FSTORE_0, FSTORE_1, FSTORE_2, FSTORE_3, FSUB, FULL_FRAME, GETFIELD, GETFIELD_QUICK, GETFIELD_QUICK_W, GETFIELD2_QUICK, GETSTATIC, GETSTATIC_QUICK, GETSTATIC2_QUICK, GOTO, GOTO_W, I2B, I2C, I2D, I2F, I2L, I2S, IADD, IALOAD, IAND, IASTORE, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5, ICONST_M1, IDIV, IF_ACMPEQ, IF_ACMPNE, IF_ICMPEQ, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ICMPLT, IF_ICMPNE, IFEQ, IFGE, IFGT, IFLE, IFLT, IFNE, IFNONNULL, IFNULL, IINC, ILLEGAL_OPCODE, ILLEGAL_TYPE, ILOAD, ILOAD_0, ILOAD_1, ILOAD_2, ILOAD_3, IMPDEP1, IMPDEP2, IMUL, INEG, INSTANCEOF, INSTANCEOF_QUICK, INT2BYTE, INT2CHAR, INT2SHORT, INTERFACES_IMPLEMENTED_BY_ARRAYS, INVOKEDYNAMIC, INVOKEINTERFACE, INVOKEINTERFACE_QUICK, INVOKENONVIRTUAL, INVOKENONVIRTUAL_QUICK, INVOKESPECIAL, INVOKESTATIC, INVOKESTATIC_QUICK, INVOKESUPER_QUICK, INVOKEVIRTUAL, INVOKEVIRTUAL_QUICK, INVOKEVIRTUAL_QUICK_W, INVOKEVIRTUALOBJECT_QUICK, IOR, IREM, IRETURN, ISHL, ISHR, ISTORE, ISTORE_0, ISTORE_1, ISTORE_2, ISTORE_3, ISUB, ITEM_Bogus, ITEM_Double, ITEM_Float, ITEM_InitObject, ITEM_Integer, ITEM_Long, ITEM_NAMES, ITEM_NewObject, ITEM_Null, ITEM_Object, IUSHR, IXOR, JSR, JSR_W, KNOWN_ATTRIBUTES, L2D, L2F, L2I, LADD, LALOAD, LAND, LASTORE, LCMP, LCONST_0, LCONST_1, LDC, LDC_QUICK, LDC_W, LDC_W_QUICK, LDC2_W, LDC2_W_QUICK, LDIV, LLOAD, LLOAD_0, LLOAD_1, LLOAD_2, LLOAD_3, LMUL, LNEG, LOOKUPSWITCH, LOR, LREM, LRETURN, LSHL, LSHR, LSTORE, LSTORE_0, LSTORE_1, LSTORE_2, LSTORE_3, LSUB, LUSHR, LXOR, MAJOR, MAJOR_1_1, MAJOR_1_2, MAJOR_1_3, MAJOR_1_4, MAJOR_1_5, MAJOR_1_6, MAJOR_1_7, MAJOR_1_8, MAX_ACC_FLAG, MAX_BYTE, MAX_CODE_SIZE, MAX_CP_ENTRIES, MAX_SHORT, MINOR, MINOR_1_1, MINOR_1_2, MINOR_1_3, MINOR_1_4, MINOR_1_5, MINOR_1_6, MINOR_1_7, MINOR_1_8, MONITORENTER, MONITOREXIT, MULTIANEWARRAY, MULTIANEWARRAY_QUICK, NEW, NEW_QUICK, NEWARRAY, NO_OF_OPERANDS, NOP, OPCODE_NAMES, POP, POP2, PRODUCE_STACK, PUSH, PUTFIELD, PUTFIELD_QUICK, PUTFIELD_QUICK_W, PUTFIELD2_QUICK, PUTSTATIC, PUTSTATIC_QUICK, PUTSTATIC2_QUICK, RESERVED, RET, RETURN, SALOAD, SAME_FRAME, SAME_FRAME_EXTENDED, SAME_FRAME_MAX, SAME_LOCALS_1_STACK_ITEM_FRAME, SAME_LOCALS_1_STACK_ITEM_FRAME_EXTENDED, SAME_LOCALS_1_STACK_ITEM_FRAME_MAX, SASTORE, SHORT_TYPE_NAMES, SIPUSH, STATIC_INITIALIZER_NAME, SWAP, SWITCH, T_ADDRESS, T_ARRAY, T_BOOLEAN, T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_OBJECT, T_REFERENCE, T_SHORT, T_UNKNOWN, T_VOID, TABLESWITCH, TYPE_NAMES, TYPE_OF_OPERANDS, UNDEFINED, UNPREDICTABLE, WIDE
      • Fields inherited from interface edu.umd.cs.findbugs.Priorities

        EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY
    • Constructor Summary

      Constructors 
      Constructor Description
      ExceptionSoftening​(edu.umd.cs.findbugs.BugReporter bugReporter)
      constructs a EXS detector given the reporter to report bugs on.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> buildConstrainingInfo​(org.apache.bcel.classfile.JavaClass cls, org.apache.bcel.classfile.Method m)
      returns exception names describing what exceptions are allowed to be thrown
      private static java.util.LinkedHashMap<java.lang.Integer,​org.apache.bcel.classfile.CodeException> collectExceptions​(org.apache.bcel.classfile.CodeException... exceptions)
      collects all the valid exception objects (ones where start and finish are before the target) and with a catch type
      private static org.apache.bcel.classfile.Method findMethod​(org.apache.bcel.classfile.JavaClass cls, java.lang.String methodName, java.lang.String methodSig)
      finds a method that matches the name and signature in the given class
      private static java.util.Set<java.lang.String> findPossibleCatchSignatures​(java.util.List<ExceptionSoftening.CatchInfo> infos, int pc)
      returns an array of catch types that the current pc is in
      private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> getConstrainingInfo​(org.apache.bcel.classfile.JavaClass cls, org.apache.bcel.classfile.Method m)
      finds the super class or interface that constrains the types of exceptions that can be thrown from the given method
      private boolean prescreen​(org.apache.bcel.classfile.Method method)
      returns whether a method explicitly throws an exception
      private void processBooleanReturn()  
      private void processThrow()  
      private static void removeFinishedCatchBlocks​(java.lang.Iterable<ExceptionSoftening.CatchInfo> infos, int pc)
      remove catchinfo blocks from the map where the handler end is before the current pc
      void sawOpcode​(int seen)
      overrides the visitor to find catch blocks that throw runtime exceptions
      private void updateEndPCsOnCatchRegScope​(java.util.List<ExceptionSoftening.CatchInfo> infos, int pc, int seen)
      reduces the end pc based on the optional LocalVariableTable's exception register scope
      void visitClassContext​(edu.umd.cs.findbugs.ba.ClassContext classContext)
      overrides the visitor to reset the stack
      void visitCode​(org.apache.bcel.classfile.Code obj)
      overrides the visitor to look for methods that catch checked exceptions and rethrow runtime exceptions
      • Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector

        getClassContext, report, shouldVisitCode
      • Methods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode

        afterOpcode, areOppositeBranches, atCatchBlock, beforeOpcode, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefConstantOperand, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visit
      • Methods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor

        getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotation
      • Methods inherited from class edu.umd.cs.findbugs.visitclass.PreorderVisitor

        amVisitingMainMethod, asUnsignedByte, doVisitMethod, getClassDescriptor, getClassName, getCode, getConstantPool, getDottedClassName, getDottedFieldSig, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitStackMapTable, visitStackMapTableEntry
      • Methods inherited from class edu.umd.cs.findbugs.visitclass.BetterVisitor

        clone, report, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitStackMap, visitStackMapEntry, visitSynthetic, visitUnknown
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • bugReporter

        private final edu.umd.cs.findbugs.BugReporter bugReporter
      • runtimeClass

        private org.apache.bcel.classfile.JavaClass runtimeClass
      • stack

        private edu.umd.cs.findbugs.OpcodeStack stack
      • catchHandlerPCs

        private java.util.Map<java.lang.Integer,​org.apache.bcel.classfile.CodeException> catchHandlerPCs
      • lvt

        private org.apache.bcel.classfile.LocalVariableTable lvt
      • constrainingInfo

        private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> constrainingInfo
      • isBooleanMethod

        private boolean isBooleanMethod
      • hasValidFalseReturn

        private boolean hasValidFalseReturn
      • catchFalseReturnPC

        private int catchFalseReturnPC
    • Constructor Detail

      • ExceptionSoftening

        public ExceptionSoftening​(edu.umd.cs.findbugs.BugReporter bugReporter)
        constructs a EXS detector given the reporter to report bugs on.
        Parameters:
        bugReporter - the sync of bug reports
    • Method Detail

      • visitClassContext

        public void visitClassContext​(edu.umd.cs.findbugs.ba.ClassContext classContext)
        overrides the visitor to reset the stack
        Specified by:
        visitClassContext in interface edu.umd.cs.findbugs.Detector
        Overrides:
        visitClassContext in class edu.umd.cs.findbugs.BytecodeScanningDetector
        Parameters:
        classContext - the context object of the currently parsed class
      • visitCode

        public void visitCode​(org.apache.bcel.classfile.Code obj)
        overrides the visitor to look for methods that catch checked exceptions and rethrow runtime exceptions
        Specified by:
        visitCode in interface org.apache.bcel.classfile.Visitor
        Overrides:
        visitCode in class edu.umd.cs.findbugs.visitclass.PreorderVisitor
        Parameters:
        obj - the context object of the currently parsed code block
      • sawOpcode

        public void sawOpcode​(int seen)
        overrides the visitor to find catch blocks that throw runtime exceptions
        Overrides:
        sawOpcode in class edu.umd.cs.findbugs.visitclass.DismantleBytecode
        Parameters:
        seen - the opcode of the currently parsed instruction
      • processThrow

        private void processThrow()
      • processBooleanReturn

        private void processBooleanReturn()
      • collectExceptions

        private static java.util.LinkedHashMap<java.lang.Integer,​org.apache.bcel.classfile.CodeException> collectExceptions​(org.apache.bcel.classfile.CodeException... exceptions)
        collects all the valid exception objects (ones where start and finish are before the target) and with a catch type
        Parameters:
        exceptions - the exceptions from the class file
        Returns:
        the filtered exceptions keyed by catch end pc
      • removeFinishedCatchBlocks

        private static void removeFinishedCatchBlocks​(java.lang.Iterable<ExceptionSoftening.CatchInfo> infos,
                                                      int pc)
        remove catchinfo blocks from the map where the handler end is before the current pc
        Parameters:
        infos - the exception handlers installed
        pc - the current pc
      • updateEndPCsOnCatchRegScope

        private void updateEndPCsOnCatchRegScope​(java.util.List<ExceptionSoftening.CatchInfo> infos,
                                                 int pc,
                                                 int seen)
        reduces the end pc based on the optional LocalVariableTable's exception register scope
        Parameters:
        infos - the list of active catch blocks
        pc - the current pc
        seen - the currently parsed opcode
      • findPossibleCatchSignatures

        private static java.util.Set<java.lang.String> findPossibleCatchSignatures​(java.util.List<ExceptionSoftening.CatchInfo> infos,
                                                                                   int pc)
        returns an array of catch types that the current pc is in
        Parameters:
        infos - the list of catch infos for this method
        pc - the current pc
        Returns:
        an set of catch exception types that the pc is currently in
      • getConstrainingInfo

        @Nullable
        private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> getConstrainingInfo​(org.apache.bcel.classfile.JavaClass cls,
                                                                                                          org.apache.bcel.classfile.Method m)
                                                                                                   throws java.lang.ClassNotFoundException
        finds the super class or interface that constrains the types of exceptions that can be thrown from the given method
        Parameters:
        cls - the currently parsed class
        m - the method to check
        Returns:
        a map containing the class name to a set of exceptions that constrain this method
        Throws:
        java.lang.ClassNotFoundException - if a super class or super interface can't be loaded from the repository
      • findMethod

        @Nullable
        private static org.apache.bcel.classfile.Method findMethod​(org.apache.bcel.classfile.JavaClass cls,
                                                                   java.lang.String methodName,
                                                                   java.lang.String methodSig)
        finds a method that matches the name and signature in the given class
        Parameters:
        cls - the class to look in
        methodName - the name to look for
        methodSig - the signature to look for
        Returns:
        the method or null
      • buildConstrainingInfo

        private java.util.Map<java.lang.String,​java.util.Set<java.lang.String>> buildConstrainingInfo​(org.apache.bcel.classfile.JavaClass cls,
                                                                                                            org.apache.bcel.classfile.Method m)
                                                                                                     throws java.lang.ClassNotFoundException
        returns exception names describing what exceptions are allowed to be thrown
        Parameters:
        cls - the cls to find the exceptions in
        m - the method to add exceptions from
        Returns:
        a map with one entry of a class name to a set of exceptions that constrain what can be thrown.
        Throws:
        java.lang.ClassNotFoundException - if an exception class can't be loaded from the repository
      • prescreen

        private boolean prescreen​(org.apache.bcel.classfile.Method method)
        returns whether a method explicitly throws an exception
        Parameters:
        method - the currently parsed method
        Returns:
        if the method throws an exception