Java & Static Analysis

by Amit Chaturvedi 



Example 1:



switch (expr) {

  case c1:

        statements // do these if expr == c1

        break;

  case c2: 

        statements // do these if expr == c2

        break;

  case c2:

}



Example 2:



class TestResourceLeak



{

    public CoreResponse process(Entit entity) throws ResourceException {

        CoreResponse coreresponse = new CoreResponse();

        DatabaseConnection dbcon = new DatabaseConnection();

        Connection con1 = null;

        Connection con2 = null;

        //getting the Data Base Connection

        try

        {

            con1 = dbcon.getConnection();

            con2 = dbcon.getConnection();

            ...

        }

        catch(Exception e)

        {

            con1.close();

            throw new ResourceException(e.getMessage(),e) ;

        }

        con1.close();

        return coreresponse;

    }   

}





Example 3:



public int CheckCC(int x) {

  int value = 0;

  if (x == 0)  {

    value = 100;

  } else {

    value = 10;

  }

  return value;      

}





Listing One



public class  GenerateAST {

  private String printFuncName() {

    System.out.println(funcName + "Generate AST"); 

  }

}

CompilationUnit

 TypeDeclaration

  ClassDeclaration:(public)

   UnmodifiedClassDeclaration(GenerateAST)

    ClassBody

     ClassBodyDeclaration

      MethodDeclaration:(private)

       ResultType

        Type

         Name:String

       MethodDeclarator(printFuncName)

        FormalParameters

       Block

        BlockStatement

         Statement

          StatementExpression

           PrimaryExpression

            PrimaryPrefix

             Name:System.out.println

            PrimarySuffix

             Arguments

              ArgumentList

               Expression

                AdditiveExpression:+

                 PrimaryExpression

                  PrimaryPrefix

                   Name:funcName

                 PrimaryExpression

                  PrimaryPrefix

                   Literal:"Generate AST"



Listing Two



import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;



import com.ddj.ast.ASTAdditiveExpression;

import com.ddj.ast.ASTBlockStatement;

import com.ddj.ast.ASTExpression;

import com.ddj.ast.ASTForStatement;

import com.ddj.ast.ASTLocalVariableDeclaration;

import com.ddj.ast.ASTMethodDeclaration;

import com.ddj.ast.ASTName;

import com.ddj.ast.ASTVariableDeclarator;

import com.ddj.ast.ASTVariableDeclaratorId;



public class StringConcatInForRule {

    static int lineNo = 0;



    public Object visitRule(ASTForStatement node, Object data) {

        ASTMethodDeclaration method = (ASTMethodDeclaration) node

                .getFirstParentOfType(ASTMethodDeclaration.class);

        List localvars = new ArrayList();

        if (method != null) {

            method.findChildrenOfType(ASTLocalVariableDeclaration.class,

                    localvars, true);

            for (Iterator lvars = localvars.iterator(); lvars.hasNext();) {

                ASTLocalVariableDeclaration localvar = 

                      (ASTLocalVariableDeclaration) lvars.next();

                if (localvar.jjtGetChild(0).jjtGetChild(0) 

                                                       instanceof ASTName) {

                    ASTName localVarName = (ASTName) localvar.jjtGetChild(0)

                            .jjtGetChild(0);

                    if (localVarName.getImage().equals("String")) {

                        if (localvar.jjtGetChild(1) 

                                         instanceof ASTVariableDeclarator) {

                            ASTVariableDeclaratorId varId = 

                                (ASTVariableDeclaratorId) localvar

                                        .jjtGetChild(1).jjtGetChild(0);

                            checkForConcat(node, varId.getImage(), data);

                        }

                    }

                }

            }

        }

        return data;

    }

    public boolean checkForConcat(ASTForStatement node, String varName,

            Object data) {

        boolean closed = false;

        List blocks = new ArrayList();

        int oldLineNo = 0;

        node.findChildrenOfType(ASTBlockStatement.class, blocks, true);

        for (Iterator it2 = blocks.iterator(); it2.hasNext();) {

            ASTBlockStatement block = (ASTBlockStatement) it2.next();

            List exps = new ArrayList();

            block.findChildrenOfType(ASTExpression.class, exps, true);

            for (Iterator it = exps.iterator(); it.hasNext();) {

               ASTExpression exp = (ASTExpression) it.next();

                if (exp.jjtGetChild(0) instanceof ASTAdditiveExpression) {

                    List names = new ArrayList();

                    exp.findChildrenOfType(ASTName.class, names, true);

                    for (Iterator it1 = names.iterator(); it1.hasNext();) {

                        ASTName name = (ASTName) it1.next();

                        if (name.getImage().equals(varName)) {

                            lineNo = block.getBeginLine();

                            if (oldLineNo != lineNo) {

                                System.out.println("String Concatenation in 

                                        loop at line no. " + lineNo +

                                                  " use Stringbuffer");

                            }

                            closed = true;

                            oldLineNo = lineNo;

                        }



                    }

                }

            }

        }

        return closed;

    }

}





Listing Three



Compiled from CreateObjects.java

public class CreateObjects extends SimpleObjects {

    public CreateObjects();

    public java.lang.String create();

}



Method CreateObjects()

   0 aload_0

   1 invokespecial #1 <Method SimpleObjects()>

   4 return



Method java.lang.String create()

   0 new #2 <Class java.lang.String>

   3 dup

   4 invokespecial #3 <Method java.lang.String()>

   7 areturn



Listing Four 



// FindClassInheritanceDepth.java



import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.IOException;

import java.util.zip.ZipEntry;

import java.util.zip.ZipInputStream;

import org.apache.bcel.classfile.ClassParser;

import org.apache.bcel.classfile.JavaClass;



public class FindClassInheritanceDepth {

    private static ZipInputStream zipInputStream;

    private static ClassParser classParser;

    private static FileInputStream fileInputStream;

    private static final int MAX_INHERETANCE_DEPTH = 5;

    

    static String getFileExtension(String fileName) {

        int lastDot = fileName.lastIndexOf('.');

        return (lastDot >= 0) ? fileName.substring(lastDot) : null;

    }



    static int CheckClassDepth(JavaClass javaClass) {

        int inheritanceDepth = 0;

        try {

            JavaClass[] aJavaClass = javaClass.getSuperClasses();

            JavaClass[] aJavaInterfaces = javaClass.getAllInterfaces();

            inheritanceDepth = aJavaClass.length + aJavaInterfaces.length;

        } catch (ClassNotFoundException cnfe) {

            System.out.println("Base Class: " + javaClass.getClassName());

            cnfe.printStackTrace();

        }

        return inheritanceDepth;

    }

    public static void main(String args[]) {

        

        if (args.length == 0) {

          System.out.println("Usage: java FindClassInheritanceDepth jarFile");

          return;

        }

        try {

            fileInputStream = new FileInputStream(args[0]);



        } catch (FileNotFoundException fe) {

            fe.printStackTrace();

        }

        zipInputStream = new ZipInputStream(fileInputStream);

        for (;;) {

            try {

                ZipEntry zipEntry = zipInputStream.getNextEntry();

                if (zipEntry == null) {

                    return;

                }

                String fileExtension = getFileExtension(zipEntry.getName());

                if (fileExtension != null) {

                    if (fileExtension.equals(".class")) {

                        classParser = new ClassParser(args[0], zipEntry

                                .getName());

                        JavaClass jClass = classParser.parse();

                        if(CheckClassDepth(jClass) > MAX_INHERETANCE_DEPTH)

                            System.out.println("Class: "+ 

                                 jClass.getClassName() + 

                                   " have excedded inheretance hierarchy 

                                         limit(max 5 is allowed)" + "\n");

                    }

                }

            } catch (IOException ie) {

               ie.printStackTrace();

            }

        }

    }

}

















5



