[Java] EclipseのJavaコンパイラをコマンドラインとAPIで呼び出してみる

2018年11月26日月曜日

Java

JDT Core batch compiler

EclipseのGUIメニューからJavaのビルドを実行すると、JavaのコンパイラはEclipseが内蔵しているコンパイラが使われる。
これはJDT Coreのbatch compilerと呼ばれる機能で、jarを指定すれば、Eclipseの外からもjavaコマンドで実行することができる。

Using the batch compiler

Eclipse Compiler for Java

特にこの機能だけを使いたい場合は、ECJ(Eclipse Compiler for Java)のjarだけで、使うこともできる。

http://download.eclipse.org/eclipse/downloads/drops4/R-4.9-201809060745/

local/Sample.javaコンパイル例
$ java -jar path/to/ecj.jar -1.8 local/Sample.java

API

APIとして、Javaから呼び出すこともできる。
先ほどのbatch compilerのヘルプページの例ではBatchCompiler.compileのprogress引数にnullを渡しているけど、CompilationProgressを継承したクラスを渡すことによって、コンパイルの進行状況を受け取ることができる。

package local;

import java.io.PrintWriter;

import org.eclipse.jdt.core.compiler.CompilationProgress;
import org.eclipse.jdt.core.compiler.batch.BatchCompiler;

class EcjSample {
    static class MyCompilationProgress extends CompilationProgress {
        @Override public void begin(int remainingWork) {
            System.out.println(0 + "/" + remainingWork);
        }

        @Override public void done() {
            System.out.println("finish.");
        }

        @Override public boolean isCanceled() {
            System.out.println("is canceled?");
            return false;
        }

        @Override public void setTaskName(String name) {
            System.out.println(name);
        }

        @Override public void worked(int workIncrement, int remainingWork) {
            System.out.println(workIncrement + "/" + 
                               (workIncrement + remainingWork));
        }
    }

    public static void main(String ... args) {
        BatchCompiler.compile("-1.8 local/Sample.java",
                              new PrintWriter(System.out),
                              new PrintWriter(System.err),
                              new MyCompilationProgress());
    }
}
$ java -cp /path/to/ecj.jar:. local.EcjSample
0/1
is canceled?
Beginning to compile
is canceled?
Processing /path/to/local/Sample.java
is canceled?
1/1
finish.
is canceled?

各処理の時点で isCanceled が呼ばれるので、バッチコンパイルをキャンセルしたい場合は true を返せばいい。

CompilationProgress