Package com.mebigfatguy.fbcontrib.detect
Class JPAIssues
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.JPAIssues
- All Implemented Interfaces:
edu.umd.cs.findbugs.Detector,edu.umd.cs.findbugs.Priorities,org.apache.bcel.classfile.Visitor
@CustomUserValue
public class JPAIssues
extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for various issues around the use of the Java Persistence API (JPA)
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static enum(package private) static enum -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Patternprivate edu.umd.cs.findbugs.BugReporterprivate org.apache.bcel.classfile.JavaClassprivate JPAIssues.TransactionalTypeprivate booleanprivate booleanprivate booleanprivate booleanprivate booleanprivate booleanprivate booleanprivate JPAIssues.TransactionalTypeprivate org.apache.bcel.classfile.JavaClassprivate edu.umd.cs.findbugs.OpcodeStackprivate Map<FQMethod, JPAIssues.TransactionalType> Fields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINTFields inherited from interface edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionJPAIssues(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a JPA detector given the reporter to report bugs on -
Method Summary
Modifier and TypeMethodDescriptionprivate voidcatalogClass(org.apache.bcel.classfile.JavaClass clz) parses the current class for spring-tx and jpa annotations, as well as hashCode and equals methods.private voidcatalogFieldOrMethod(org.apache.bcel.classfile.FieldOrMethod fm) parses a field or method for spring-tx or jpa annotationsprivate Set<org.apache.bcel.classfile.JavaClass> getAnnotatedRollbackExceptions(org.apache.bcel.classfile.Method method) parses an spring-tx @Transactional annotations for rollbackFor/noRollbackfor attributes of a @Transactional annotation.private Set<org.apache.bcel.classfile.JavaClass> getDeclaredExceptions(org.apache.bcel.classfile.Method method) retrieves the set of non-runtime exceptions that are declared to be thrown by the methodprivate JPAIssues.TransactionalTypegetTransactionalType(FQMethod method) returns the type of transactional annotation is applied to this methodprivate JPAIssues.TransactionalTypegetTransactionalType(org.apache.bcel.classfile.Method method) returns the type of transactional annotation is applied to this methodprivate JPAIssues.JPAUserValueprivate voidreportExceptionMismatch(org.apache.bcel.classfile.Method method, Set<org.apache.bcel.classfile.JavaClass> expectedExceptions, Set<org.apache.bcel.classfile.JavaClass> actualExceptions, boolean checkByDirectionally, BugType bugType) compares the current methods exceptions to those declared in the spring-tx's @Transactional method, both rollbackFor and noRollbackFor.voidsawOpcode(int seen) implements the visitor to look for calls to @Transactional methods that do not go through a spring proxy.voidvisitClassContext(edu.umd.cs.findbugs.ba.ClassContext clsContext) implements the visitor to find @Entity classes that have both generated @Ids and have implemented hashCode/equals.voidvisitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the opcode stack, Note that the synthetic check is done in both visitMethod and visitCode as visitMethod is not a proper listener stopping method.voidvisitMethod(org.apache.bcel.classfile.Method obj) implements the visitor to look for non public methods that have an @Transactional annotation applied to it.Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCodeMethods 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, visitMethods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotationMethods 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, getSurroundingCaughtExceptionTypes, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitBootstrapMethods, visitConstantInvokeDynamic, visitConstantMethodHandle, visitConstantMethodType, visitConstantModule, visitConstantPackage, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitMethodParameters, visitParameterAnnotationEntry, visitStackMap, visitStackMapEntryMethods 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, visitSignature, visitSourceFile, visitSynthetic, visitUnknownMethods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.bcel.classfile.Visitor
visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
-
Field Details
-
annotationClassPattern
-
bugReporter
private edu.umd.cs.findbugs.BugReporter bugReporter -
runtimeExceptionClass
private org.apache.bcel.classfile.JavaClass runtimeExceptionClass -
cls
private org.apache.bcel.classfile.JavaClass cls -
stack
private edu.umd.cs.findbugs.OpcodeStack stack -
transactionalMethods
-
clsTransactionalType
-
isEntity
private boolean isEntity -
hasId
private boolean hasId -
hasGeneratedValue
private boolean hasGeneratedValue -
hasEagerOneToMany
private boolean hasEagerOneToMany -
hasFetch
private boolean hasFetch -
hasHCEquals
private boolean hasHCEquals -
methodTransType
-
isPublic
private boolean isPublic
-
-
Constructor Details
-
JPAIssues
public JPAIssues(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a JPA detector given the reporter to report bugs on- Parameters:
bugReporter- the sync of bug reports
-
-
Method Details
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext clsContext) implements the visitor to find @Entity classes that have both generated @Ids and have implemented hashCode/equals. Also looks for eager one to many join fetches as that leads to 1+n queries.- Specified by:
visitClassContextin interfaceedu.umd.cs.findbugs.Detector- Overrides:
visitClassContextin classedu.umd.cs.findbugs.BytecodeScanningDetector- Parameters:
clsContext- the context object of the currently parsed class
-
visitMethod
public void visitMethod(org.apache.bcel.classfile.Method obj) implements the visitor to look for non public methods that have an @Transactional annotation applied to it. Spring only scans public methods for special handling. It also looks to see if the exceptions thrown by the method line up with the declared exceptions handled in the @Transactional annotation.- Specified by:
visitMethodin interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitMethodin classedu.umd.cs.findbugs.visitclass.BetterVisitor- Parameters:
obj- the currently parse method
-
visitCode
public void visitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the opcode stack, Note that the synthetic check is done in both visitMethod and visitCode as visitMethod is not a proper listener stopping method. We don't want to report issues reported in visitMethod if it is synthetic, but we also don't want it to get into sawOpcode, so that is why it is done here as well.- Specified by:
visitCodein interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitCodein classedu.umd.cs.findbugs.visitclass.PreorderVisitor- Parameters:
obj- the currently parsed code block
-
sawOpcode
public void sawOpcode(int seen) implements the visitor to look for calls to @Transactional methods that do not go through a spring proxy. These methods are easily seen as internal class calls. There are other cases as well, from external/internal classes but these aren't reported.- Overrides:
sawOpcodein classedu.umd.cs.findbugs.visitclass.DismantleBytecode- Parameters:
seen- the currently parsed opcode
-
processInvoke
-
catalogClass
private void catalogClass(org.apache.bcel.classfile.JavaClass clz) parses the current class for spring-tx and jpa annotations, as well as hashCode and equals methods.- Parameters:
clz- the currently parsed class
-
catalogFieldOrMethod
private void catalogFieldOrMethod(org.apache.bcel.classfile.FieldOrMethod fm) parses a field or method for spring-tx or jpa annotations- Parameters:
fm- the currently parsed field or method
-
reportExceptionMismatch
private void reportExceptionMismatch(org.apache.bcel.classfile.Method method, Set<org.apache.bcel.classfile.JavaClass> expectedExceptions, Set<org.apache.bcel.classfile.JavaClass> actualExceptions, boolean checkByDirectionally, BugType bugType) compares the current methods exceptions to those declared in the spring-tx's @Transactional method, both rollbackFor and noRollbackFor. It looks both ways, exceptions thrown that aren't handled by rollbacks/norollbacks, and Spring declarations that aren't actually thrown.- Parameters:
method- the currently parsed methodexpectedExceptions- exceptions declared in the @Transactional annotationactualExceptions- non-runtime exceptions that are thrown by the methodcheckByDirectionally- whether to check both waysbugType- what type of bug to report if found
-
getAnnotatedRollbackExceptions
private Set<org.apache.bcel.classfile.JavaClass> getAnnotatedRollbackExceptions(org.apache.bcel.classfile.Method method) throws ClassNotFoundException parses an spring-tx @Transactional annotations for rollbackFor/noRollbackfor attributes of a @Transactional annotation.- Parameters:
method- the currently parsed method- Returns:
- the exception classes declared in the @Transactional annotation
- Throws:
ClassNotFoundException- if exception classes are not found
-
getDeclaredExceptions
private Set<org.apache.bcel.classfile.JavaClass> getDeclaredExceptions(org.apache.bcel.classfile.Method method) throws ClassNotFoundException retrieves the set of non-runtime exceptions that are declared to be thrown by the method- Parameters:
method- the currently parsed method- Returns:
- the set of exceptions thrown
- Throws:
ClassNotFoundException- if an exception class is not found
-
getTransactionalType
returns the type of transactional annotation is applied to this method- Parameters:
method- the method to check for transactional methods- Returns:
- whether the method is Transactional non, read or write
-
getTransactionalType
returns the type of transactional annotation is applied to this method- Parameters:
method- the method to check for transactional methods- Returns:
- whether the method is Transactional non, read or write
-