Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.mebigfatguy.fbcontrib.detect;
  
  import java.util.Arrays;
  import java.util.BitSet;
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
 
 import  org.apache.bcel.Constants;
 import  org.apache.bcel.Repository;
 import  org.apache.bcel.classfile.Code;
 import  org.apache.bcel.classfile.CodeException;
 import  org.apache.bcel.classfile.ConstantClass;
 import  org.apache.bcel.classfile.ConstantPool;
 import  org.apache.bcel.classfile.JavaClass;
 import  org.apache.bcel.generic.Type;
 
 import  edu.umd.cs.findbugs.BugInstance;
 import  edu.umd.cs.findbugs.BugReporter;
 import  edu.umd.cs.findbugs.BytecodeScanningDetector;
 import  edu.umd.cs.findbugs.OpcodeStack;
 import  edu.umd.cs.findbugs.ba.ClassContext;
 import  edu.umd.cs.findbugs.ba.XMethod;

looks for two or more try catch blocks that are consecutive and catch the same kind of exception, and throw the same exception always. These blocks can be coalesced into one.
 
 
 public class StackedTryBlocks extends BytecodeScanningDetector {
 
     private static JavaClass THROWABLE_CLASS;
     
     static {
         try {
              = Repository.lookupClass("java.lang.Throwable");
         } catch (ClassNotFoundException cnfe) {
              = null;
         }
     }
 	private final BugReporter bugReporter;
 	private List<TryBlockblocks;
 	private List<TryBlockinBlocks;
 	private OpcodeStack stack;
 
 	public StackedTryBlocks(BugReporter bugReporter) {
 		this. = bugReporter;
 	}
 
 	public void visitClassContext(ClassContext classContext) {
 		try {
 		    if ( != null) {
     			 = new OpcodeStack();
     			super.visitClassContext(classContext);
 		    }
 		} finally {
 			 = null;
 		}
 	}
 
 	public void visitCode(Code obj) {
 
 		try {
 			XMethod xMethod = getXMethod();
 			String[] tes = xMethod.getThrownExceptions();
 			Set<StringthrownExceptions = new HashSet<String>(Arrays.<StringasList((tes == null) ? new String[0] : tes));
 
 			 = new ArrayList<TryBlock>();
 			 = new ArrayList<TryBlock>();
 
 			CodeException[] ces = obj.getExceptionTable();
 			for (CodeException ce : ces) {
 				TryBlock tb = new TryBlock(ce);
 				int existingBlock = .indexOf(tb);
 				if (existingBlock >= 0) {
 					tb = .get(existingBlock);
 					tb.addCatchType(ce);
 				} else {
 					.add(tb);
 				}
 			}
 
 			while (it.hasNext()) {
 				TryBlock block = it.next();
 				if (block.hasMultipleHandlers() || block.isFinally()
 						|| block.catchIsThrown(getConstantPool(), thrownExceptions)) {
 					it.remove();
 				}
 			}
 
 			if (.size() > 1) {
 				.resetForMethodEntry(this);
 				super.visitCode(obj);
				if (.size() > 1) {
					TryBlock firstBlock = .get(0);
					for (int i = 1; i < .size(); i++) {
						TryBlock secondBlock = .get(i);
						if ((firstBlock.getCatchType() == secondBlock.getCatchType())
                                && (firstBlock.getThrowSignature().equals(secondBlock.getThrowSignature())
                                && ((firstBlock.getMessage().length() > 0) && firstBlock.getMessage().equals(secondBlock.getMessage())
								&& (firstBlock.getExceptionSignature().equals(secondBlock.getExceptionSignature()))))) {
							.reportBug(new BugInstance(this"STB_STACKED_TRY_BLOCKS", NORMAL_PRIORITY)
									.addClass(this).addMethod(this)
									.addSourceLineRange(thisfirstBlock.getStartPC(), firstBlock.getEndHandlerPC())
									.addSourceLineRange(thissecondBlock.getStartPC(), secondBlock.getEndHandlerPC()));
						}
						firstBlock = secondBlock;
					}
				}
			}
finally {
			 = null;
			 = null;
		}
	}
	public void sawOpcode(int seen) {
	    String message = null;
		try {
			int pc = getPC();
			if (block != null) {
				.add(block);
			}
			if (.size() > 0) {
				TryBlock innerBlock = .get(.size() - 1);
				int nextPC = getNextPC();
				if (innerBlock.atHandlerPC(nextPC)) {
					if ((seen == GOTO) || (seen == GOTO_W)) {
else {
						.remove(innerBlock);
						.remove(innerBlock);
					}
else if (innerBlock.atHandlerPC(pc)) {
else if (innerBlock.atEndHandlerPC(pc)) {
				}
				if (innerBlock.inCatch()) {
					if (((seen >= Constants.IFEQ) && ((seen <= Constants.RET)))
							|| ((seen >= Constants.IRETURN) && (seen <= Constants.RETURN)) || (seen == GOTO_W)) {
						.remove(innerBlock);
else if (seen == ATHROW) {
						if (.getStackDepth() > 0) {
							OpcodeStack.Item item = .getStackItem(0);
							XMethod xm = item.getReturnValueOf();
							if (xm != null) {
							    innerBlock.setThrowSignature(xm.getSignature());
							}
                            innerBlock.setExceptionSignature(item.getSignature());
                            innerBlock.setMessage((Stringitem.getUserValue());
else {
						}
else if ((seen == INVOKESPECIAL) && "<init>".equals(getNameConstantOperand())) {
					    String cls = getClassConstantOperand();
					    JavaClass exCls = Repository.lookupClass(cls);
					    if (exCls.instanceOf()) {
					        String signature = getSigConstantOperand();
					        Type[] types = Type.getArgumentTypes(signature);
					        if ((types.length > 0) && "Ljava/lang/String;".equals(types[0].getSignature())) {
					            if (.getStackDepth() >= types.length) {
					                OpcodeStack.Item item = .getStackItem(types.length - 1);
					                message = (String)item.getConstant();
					                if (message == null) {
					                    message = "____UNKNOWN____" + System.currentTimeMillis();
					                }
					            }
					        }
					        
					    }
					}
				}
			}
catch (ClassNotFoundException cnfe) {
		    .reportMissingClass(cnfe);
finally {
			.sawOpcode(thisseen);
			if ((message != null) && (.getStackDepth() > 0)) {
			    OpcodeStack.Item item = .getStackItem(0);
			    item.setUserValue(message);
			}
		}
	}
	private TryBlock findBlockWithStart(int pc) {
		for (TryBlock block : ) {
			if (block.atStartPC(pc)) {
				return block;
			}
		}
		return null;
	}
	static class TryBlock {
		public enum State {
			BEFORE, IN_TRY, IN_CATCH, AFTER
		};
		int startPC;
		int endPC;
		public TryBlock(CodeException ce) {
			 = ce.getStartPC();
			 = ce.getEndPC();
			 = ce.getHandlerPC();
			 = new BitSet();
			.set(ce.getCatchType());
		}
		public void addCatchType(CodeException ce) {
			.set(ce.getCatchType());
		}
		public void setState(State executionState) {
			 = executionState;
		}
		public boolean inCatch() {
			return  == .;
		}
		public boolean hasMultipleHandlers() {
			int bit = .nextSetBit(0);
			return .nextSetBit(bit + 1) >= 0;
		}
		public boolean isFinally() {
			return .get(0);
		}
		public boolean catchIsThrown(ConstantPool poolSet<StringthrownExceptions) {
			if (thrownExceptions.size() > 0) {
				int exIndex = .nextSetBit(0);
				String exName = ((ConstantClass) pool.getConstant(exIndex)).getBytes(pool);
				return thrownExceptions.contains(exName);
			}
			return false;
		}
		public void setEndHandlerPC(int end) {
			 = end;
		}
		public void setExceptionSignature(String sig) {
		     = sig;
		}
		public void setThrowSignature(String sig) {
			 = sig;
		}
		public void setMessage(String m) {
		     = m;
		}
		    return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;
		}
			return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;
		}
		public String getMessage() {
            return ( == null) ? String.valueOf(System.identityHashCode(this)) : ;		    
		}
		public int getStartPC() {
			return ;
		}
		public int getEndHandlerPC() {
			return ;
		}
		public boolean atStartPC(int pc) {
			return  == pc;
		}
		public boolean atHandlerPC(int pc) {
			return  == pc;
		}
		public boolean atEndHandlerPC(int pc) {
			return ( >= 0) && ( == pc);
		}
		public int getCatchType() {
		}
		public int hashCode() {
			return  ^ ;
		}
		public boolean equals(Object o) {
			if (o instanceof TryBlock) {
				TryBlock that = (TryBlocko;
				return ( == that.startPC) && ( == that.endPC);
			}
			return false;
		}
		public String toString() {
			return "{" +  + " -> " +  + "} (catch " + .nextSetBit(0) + ") {" +  + " -> "
 + "}";
		}
	}
New to GrepCode? Check out our FAQ X