ant で class ファイルを dump するタスクを作った

package myomi.ant.taskdefs;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.taskdefs.MatchingTask;
import org.apache.tools.ant.types.Path;

import sun.misc.CharacterEncoder;
import sun.misc.HexDumpEncoder;

public class Dump extends MatchingTask {
    
    private Path classDirs;
    private File destDir;

    public Dump() throws ClassNotFoundException, SecurityException, NoSuchMethodException {
        super();
    }

    public void setClassDir(Path classDir) {
        if (classDirs == null) {
            classDirs = classDir;
        } else {
            classDirs.append(classDir);
        }
    }
    
    public void setDestDir(File destDir) {
        this.destDir = destDir;
    }
    
    public void execute() {
        log("start dump task");
        try {
            for (String dir: classDirs.list()) {
                File f = getProject().resolveFile(dir);
                DirectoryScanner scanner = getDirectoryScanner(f);
                String[] classes = scanner.getIncludedFiles();
                for (String classPath: classes) {
                    javap(dir, classPath);                    
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log("end dump task");
    }
    
    private void javap(String classDir, String classPath) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, ClassNotFoundException, IOException {
        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            // mkdir
            File tmp = new File(destDir.getAbsolutePath() + File.separator + classPath);
            File dir = tmp.getParentFile();
            if (!dir.exists()) dir.mkdirs();
            // dump
            in = new FileInputStream(classDir + File.separator + classPath);
            File file = new File(dir, tmp.getName().replaceAll(".class", ".dump"));
            out = new FileOutputStream(file);
            CharacterEncoder encoder = new HexDumpEncoder();
            encoder.encodeBuffer(in, out);
            log("execute dump: " + file.getAbsolutePath());
        } finally {
            try {
                if (in != null) in.close();
            } finally {
                if (out != null) out.close();
            }
        }
    }
}

使い方

<target name="dump">
  <mkdir dir="${dump.dir}"/>
  <taskdef name="dump" classname="myomi.ant.taskdefs.Dump" 
    classpath="${lib.dir}/myomiTask.jar"/>
  <dump classdir="${classes.dir}" destdir="${dump.dir}"/>
</target>

HexDumpEncoderの存在はここで知った。
http://homepage2.nifty.com/ann/Windows/tools/javap-HexDumpEncoder.htm


「ant で javap するタスクを作った」で作ったタスクと合わせて、これからいろいろと遊んでみます。