groovyからデコンパイラツールのjadをぐるぐるまわしてみる - できはよくない。
2007/08/22
2007/08/23
groovy
java
デコンパイラツールのjadを使うスクリプトをgroovyで書いてみた。
もちろん、groovyである必要はまったくないけど。
理由は、なぜかよくわからないけど、どうも標準出力と標準エラーの両方の出力があるとそうなるっぽい。でも、ほんとのところは追求していません。
ちょっとだめった感じのコードは下記のような感じ。
def command = "ジャド"
def proc = command.execute()
proc.waitFor()
def proc = command.execute()
proc.waitFor()
って何故このコードでだめなのかよくわからない。
追記:20070823 これはgroovyだからというわけではないです。groovyからは、Runtime.getRuntime().exec(self)とjava.lang.Runtimeを使用しているだけだから。
で、試行錯誤した結果、java5から導入されたProcessBuilderを使用してみてうまく動いた。
ただし、単に使うだけではなく、redirectErrorStreamをtrueにしたのが肝要ぽいです。
java5のjavadocには以下のように書いてありました。
このプロパティが true の場合、このオブジェクトの start() メソッドでそれ以降起動されたサブプロセスにより生成されるエラー出力は、標準出力とマージされます。これにより、Process.getInputStream() メソッドを使って、エラー出力と標準出力の両方を読み取ることができます。マージにより、エラーメッセージと対応する出力との相関を示すのが容易になります。初期値は false です。
javadoc api
あとファイル操作で参考
ディレクトリのファイルを再帰的にとれるのが、eachFileRecurse。
これすごく便利。
いまいちgroovyのStringの操作がよくわかってないので、おいおい練習していこうと思います。
かっこわるいけど、以下groovyコード。
import java.io.*;
if(this.args.length < 0){
println "Usage: decompile_by_jad.groovy [targetdirname]"
System.exit(0);
}
def dir = args[0]
def jad_path = "jad"; // maybe exist current dir....
new File(dir).eachFileRecurse{ f ->
if((f as String).endsWith(".class") && !( (f as String).contains('$') )){
println "=====================================";
println f;
def command = "${ jad_path } -r -o -s java ${f as String}"
try {
println "execute ${ command }";
ProcessBuilder builder = new ProcessBuilder( (command as String).split(' ') );
builder.redirectErrorStream( true );
Process process = builder.start();
InputStream stream = process.getInputStream();
while (true) {
int c = stream.read();
if (c == -1) {
stream.close();
break;
}
}
} catch (e) {
println e;
}
}
}
if(this.args.length < 0){
println "Usage: decompile_by_jad.groovy [targetdirname]"
System.exit(0);
}
def dir = args[0]
def jad_path = "jad"; // maybe exist current dir....
new File(dir).eachFileRecurse{ f ->
if((f as String).endsWith(".class") && !( (f as String).contains('$') )){
println "=====================================";
println f;
def command = "${ jad_path } -r -o -s java ${f as String}"
try {
println "execute ${ command }";
ProcessBuilder builder = new ProcessBuilder( (command as String).split(' ') );
builder.redirectErrorStream( true );
Process process = builder.start();
InputStream stream = process.getInputStream();
while (true) {
int c = stream.read();
if (c == -1) {
stream.close();
break;
}
}
} catch (e) {
println e;
}
}
}
: