The manual for Java source code search

Syntax

There is a script which checks some missing close methods automatically.
check_close.sh <file names>
You can use it like this:
./check_close.sh *.java

parsing Import.java
name: s:12 type: name: Socket methodCalls: [name: getInputStream:13] assignments: [name: newSocket():12] references: []

parsing Import.java
name: fis:17 type: name: FileInputStream methodCalls: [name: write:18] assignments: [name: newFileInputStream():17] references: []

parsing Import.java
name: fr:25 type: name: FileReader methodCalls: [] assignments: [name: newFileReader():25] references: []
The syntax for the search tool is the following:
jsearch.sh [-ver] | [-regexp] -input <search input> <file names>

-ver

shows the version information of the tool.

-regexp

is the optional parameter and says that we want to use regular
expression search patters. It is jdk 1.6 regular expression syntax.

-input <search input>

-input and "..." are the mandatory parameters for the search patterns
 There are several kind of patterns that you can use:

.import=<import statement>
variable.type=<variable object declaratation/instance creation>
variable.method_call=<object's method call>
variable.object_name=<variable object's name>
variable.statement=<Java statement>

when you give several patterns at the same time you need to separate
them with && characters. The variable.statement pattern is meant to be
used alone pattern only because it doesn't refer the variable like the
other patterns.

You can also use ! for invert match to search tokens that don't match
for the specific rule.
Here are some examples that you can search with the tool.
  1. We want to search all the variable object instances which have Stream in their name (for example FileInputStream, FileOutputStream, InputStream, etc.) and which don't have called the close method.
    ./jsearch.sh -regexp -input "variable.type=.*Stream.* &&
    variable.method_call!=close" Testi16.java
    Output:
    parsing Testi16.java
    name: fos:3 type: name: FileOutputStream methodCalls: [name: write:4]
    assignments: [name: newFileOutputStream("foo.txt"):3] references: []
    name: fis:7 type: name: FileInputStream methodCalls: [name: read:8]
    assignments: [name: newFileInputStream("foo.txt"):7] references: []
    
    finished parsing OK
    
    In the below you can see that there are only two variables (fos and
    fis in the lines 3 and 7) that miss close method calls at the end.
    
    public class Testi16 {
        public void foo() {
    	FileOutputStream fos = new FileOutputStream("foo.txt");
    	fos.write(0);
        }
        public void foo2() {
    	FileInputStream fis = new FileInputStream("foo.txt");
    	fis.read();
        }
        public void foo3() {
    	FileInputStream is = new FileInputStream("foo.txt");
    	is.read();
    	is.close();
        }
        public void foo4() {
    	FileOutputStream fos = new FileOutputStream("foo.txt");
    	fos.write(0);
    	fos.close();
        }
    }
    
    
  2. We want to search all the variable objects which have Socket instances and import statements for the java.net and which don't have called the close method.
    ./jsearch.sh -regexp -input ".import=java.net.* && variable.type=.*Socket.* &&
    variable.method_call!=close" Import.java
    Output:
    parsing Import.java 
    name: s:12 type: name: Socket methodCalls: [name: getInputStream:13]
    assignments: [name: newSocket():12] references: []
    
    
    the output shows that there is s variable object which has been
    declared in the line number 12 (name: s:12) and it is a Socket object
    (name: Socket) and it has only one method call getInputStream ([name:
    getInputStream:13]) which can found in line 13 and then there is one
    assignment ([name: newSocket():12]) for the object which can be
    found in line 12 and there are no references for the objects
    (references: []). So it doesn't have close method call at all
    so that is why it was found. You can find the test class in the below
    
    import own.PreparedStatement;
    import java.net.Socket;
    import java.io.*;
    
    public class Import {
        public void test() {
    	PreparedStatement ps = new PreparedStatement();
    	ps.executeQuery();
        }
    
        public void test2() {
    	Socket s = new Socket();
    	s.getInputStream();
        }
    
        public void test3() {
    	FileInputStream fis = new FileInputStream();
    	fis.write(1);
        }
        public void test4() {
    	RandomAccessFile raf = new RandomAccessFile();
    	raf.write(1);
        }
        public void test5() {
    	FileReader fr = new FileReader();
    	fis.write(1);
        }
        public void test6() {
    	File f = new File();
    	f.canRead();
        }
    
    }
    
    
  3. We want to search all the variable objects which have (Statement and any other characters after Statement) instances which have close (and possible any character after that) method calls and also the variable name starts with s:
    ./jsearch.sh  -regexp -input "variable.type=Statement.? &&
    variable.method_call=close.* && variable.object_name=s.*" Testi.java
    Output:
    parsing Testi.java
    name: s2:4 type: name: Statement:-1 methodCalls: [name: closeAll:6]
    assignments:
    [name: newStatement():4] references: []
    name: sss:3 type: name: Statement:-1 methodCalls: [name: close:5]
    assignments: [name: newStatement():3] references: []
    name: s2:11 type: name: Statement2:-1 methodCalls: [name: close:13]
    assignments: [name: newStatement():11] references: []
    
    As you can see in the below that there are three close method calls
    (two closes and one closeAll method call) and there are four
    Statements but one (Statement s) doesn't have close method call so it
    is not printed and all of those variable names start with s.
    
    public class Testi {
       public void foo() {
           Statement sss = new Statement();
           Statement s2 = new Statement();
           sss.close();
           s2.closeAll();
    
       }
       public void foo2() {
           Statement s;
           Statement2 s2 = new Statement();
           s.executeUpdate();
           s2.close();
       }
    }
    
    The current version of the tool notice/works only with the local variables and it doesn't notice if you give the objects for the reference for some other method calls which do the closing operations, for example:
    public class Testi13 {
        public void foo() {
            Statement s = new Statement();
            executeFinalizeThings(s);
        }
    
        private void executeFinalizeThings(Statement s) {
            s.close();
        }
    
        public void foo2() {
            Statement s = new Statement();
            s.executeUpdate();
        }
    }
    
  4. If you now try to search Statement object which haven't called the close method
    ./jsearch.sh Testi13.java -input "variable.type=Statement &&
    variable.method_call!=close"
    Output:
    parsing Testi13.java
    name: s:3 type: name: Statement methodCalls: [] assignments: [name:
    newStatement():3] references: [name: executeFinalizeThings(s);:4]
    name: s:12 type: name: Statement methodCalls: [name: executeUpdate:13]
    assignments: [name: newStatement():12] references: []
    
    finished parsing OK
    

    the tool doesn't notice that you have called the close method because the close method call is done in other method (finalizeStatements) not in the same method (foo) where the Statement declaration is done. However the tool shows you that there is a reference for that object (references: [name: executeFinalizeThings(s);:4]).

  5. We want to search the statements where the variable name i has been assigned to 5 and something.
    ./jsearch.sh Testi.java -regexp -input "variable.statement=i.*=5.*"
    Output:
    
    parsing Testi.java
    null type: null methodCalls: [] assignments: [name: if(i=5);:5] references: []
    null type: null methodCalls: [] assignments: [name: i=5;:6] references: []
    
    finished parsing OK
    
    As you can see in the below that there are two i = 5 statements 
    (if (i = 5); and i = 5;) so those two statements are printed.
    
    public class Testi {
        public void foo2() {
            int i, j, l;
            System.out.println("foobar"+(i=5));
            if (i = 5);
            i = 5;i++; l = 0;
    
            j = 3;
        }
        public void foo3() {
            int ii, jj;
            ii = 15;
            jj = 23;
        }
    }
    
Date of last update: 2011-04-23. Copyright Roni Hursti

Valid HTML 4.01 Strict