|
|
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.
-
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();
}
}
-
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();
}
}
-
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();
}
}
-
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]).
-
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;
}
}
|