Package com.mebigfatguy.fbcontrib.detect
Class ExceptionSoftening
- java.lang.Object
-
- edu.umd.cs.findbugs.visitclass.BetterVisitor
-
- edu.umd.cs.findbugs.visitclass.PreorderVisitor
-
- edu.umd.cs.findbugs.visitclass.AnnotationVisitor
-
- edu.umd.cs.findbugs.visitclass.DismantleBytecode
-
- edu.umd.cs.findbugs.BytecodeScanningDetector
-
- com.mebigfatguy.fbcontrib.detect.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
-
-
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 thrownprivate 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 typeprivate 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 classprivate 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 inprivate 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 methodprivate boolean
prescreen(org.apache.bcel.classfile.Method method)
returns whether a method explicitly throws an exceptionprivate 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 pcvoid
sawOpcode(int seen)
overrides the visitor to find catch blocks that throw runtime exceptionsprivate void
updateEndPCsOnCatchRegScope(java.util.List<ExceptionSoftening.CatchInfo> infos, int pc, int seen)
reduces the end pc based on the optional LocalVariableTable's exception register scopevoid
visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
overrides the visitor to reset the stackvoid
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
-
-
-
-
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
-
catchInfos
private java.util.List<ExceptionSoftening.CatchInfo> catchInfos
-
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
-
-
Method Detail
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
overrides the visitor to reset the stack- Specified by:
visitClassContext
in interfaceedu.umd.cs.findbugs.Detector
- Overrides:
visitClassContext
in classedu.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 interfaceorg.apache.bcel.classfile.Visitor
- Overrides:
visitCode
in classedu.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 classedu.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 installedpc
- 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 blockspc
- the current pcseen
- 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 methodpc
- 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 classm
- 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 inmethodName
- the name to look formethodSig
- 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 inm
- 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
-
-