Java コードのコンパイル

JDT プラグインには、ソース・コードから Java の .class ファイルをビルドするためのインクリメンタル Java コンパイラーおよびバッチ Java コンパイラーが含まれています。 このコンパイラーは、直接 API を提供していません。 直接 API は、Java プロジェクトに対するビルダーとしてインストールされます。 コンパイルは、プラットフォームの標準のビルド・メカニズムを使用して起動されます。

プラットフォームのビルド・メカニズムについては、 「インクリメンタル・プロジェクト・ビルダー」で詳細に説明されています。

コードのコンパイル

ビルド API を使用して、プロジェクトの Java ソース・ファイルをプログラマチックに コンパイルすることができます。

   IProject myProject;
   IProgressMonitor myProgressMonitor;
   myProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, myProgressMonitor);

Java プロジェクトの場合、このコードにより Java インクリメンタル・プロジェクト・ビルダーが (プロジェクトのビルド・スペックに追加されている他のすべてのインクリメンタル・プロジェクト・ビルダーとともに) 起動されます。 生成された .class ファイルは、指定の出力フォルダーに書き込まれます。 その他のリソース・ファイルも出力フォルダーにコピーされます。  

フル・バッチ・ビルドの場合、不整合ファイルが見つからなくなるように出力フォルダー内のすべての .class ファイルが「修正」できます。 これは、JDT コア・ビルダー・オプション (CORE_JAVA_BUILD_CLEAN_OUTPUT_FOLDER) を使用して制御できます。  このオプションのデフォルトは、出力フォルダーのクリーンです。 このオプションがリセットされていない限り、対応するソース・ファイルがない .class ファイルはすべて、 出力フォルダーではなくクラスパスの別のクラス・ファイル・フォルダーに入れる必要があります。

インクリメンタル・ビルダーおよびバッチ・ビルダーは、 どのリソースを出力フォルダーにコピーするかを制御する他のオプションを使用して構成できます。 次のサンプルは、「.ignore」で終わるファイルと「META-INF」という名前のフォルダーが出力フォルダーにコピーされないようにリソース・フィルターをセットアップする方法を示しています。

   Hashtable options = JavaCore.getOptions();
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   JavaCore.setOptions(options);

指定されたいずれかのパターンにファイル名が一致する場合、ファイル名がフィルターに掛けられます。 フォルダー名と、パス分離文字で終わる指定のフォルダー名のいずれかとが一致する場合、 そのフォルダー全体がフィルターに掛けられます。

インクリメンタル・ビルダーおよびバッチ・ビルダーは、.classpath ファイルにエラーがあるときに 1 つのエラーのみを生成するように構成することもできます。 このオプションはデフォルトで設定され、多くのエラーを除去します。 ビルダー関連オプションとそのデフォルトの詳細なリストについては、『JDT コア・ビルダー・オプション』を参照してください。

コンパイラーは、JavaCore を使用して構成することもできます。 例えば、コンパイル中に見つかるさまざまな種類の問題に使用する重大度を定義できます。 コンパイラー関連オプションとそのデフォルトに詳細なリストについては、 『JDT コア・コンパイラー・オプション』を参照してください。

ビルダーまたはコンパイラーのオプションをプログラマチックに構成するとき、 オプションのスコープを決める必要があります。 例えば、リソース・フィルターのセットアップが、特定のプロジェクトにのみ適用される場合があります。 次のサンプルでは、前に示したものと同じリソース・フィルターがセットアップされますが、 個々のプロジェクトのみに設定されます。

   
   Hashtable options = myProject.getOptions(false);  // get only the options set up in this project
   options.put(JavaCore.CORE_JAVA_BUILD_RESOURCE_COPY_FILTER, "*.ignore,META-INF/");
   myProject.setOptions(options);

ant javac アダプターの使用

Eclipse コンパイラーは、javac アダプターを使用する Ant スクリプト内で使用できます。 Eclipse コンパイラーを使用するには、スクリプトに build.compiler プロパティーを正しく定義する必要があります。 以下に、簡単な例を示します。
<?xml version="1.0" encoding="UTF-8"?>
<project name="compile" default="main" basedir="../.">

	<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter"/>

	<property name="root" value="${basedir}/src"/>

	<property name="destdir" value="d:/temp/bin" />

	<target name="main">
		<javac srcdir="${root}" destdir="${destdir}" debug="on" nowarn="on" extdirs="d:/extdirs" source="1.4">
		    <classpath>
		      <pathelement location="${basedir}/../org.eclipse.jdt.core/bin"/>
		    </classpath>
		</javac>		
	</target>
</project>
javac Ant タスクで使用される構文は、 『Ant javac タスク・ドキュメンテーション』にあります。 現行アダプターは、Javac Ant タスク 1.4.1 および 1.5.3 バージョンをサポートしています。

問題判別

JDT コアは、コンパイルの問題を示すための特別なマーカー (org.eclipse.jdt.core.problem というマーカー型) を定義します。 コンパイラーによって検出された問題を方針に基づいて発見するには、 プラットフォームの標準のマーカー・プロトコルを使用する必要があります。 マーカーの使用方法の概要については、 『リソース・マーカー』を参照してください。

以下のコードの断片により、コンパイル単位内のすべての Java 問題のマーカーが検出されます。

   public IMarker[] findJavaProblemMarkers(ICompilationUnit cu)
      throws CoreException {
      IResource javaSourceFile = cu.getUnderlyingResource();
      IMarker[] markers =
         javaSourceFile.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER,
            true, IResource.DEPTH_INFINITE);
   }

Java 問題マーカーは、Java プロジェクト・ビルダーによって保守され、問題が解決されて Java ソースが再コンパイルされると、自動的に除去されます。

問題の ID 値は、IProblem 内のいずれかの定数によって設定されます。 問題の ID は信頼性のあるものですが、メッセージはローカライズされ、デフォルト・ロケールに応じて変更されます。 IProblem に定義されている定数は自己記述です。

IProblemRequestor の実装は、Java 操作中に検出された問題を収集するように定義する必要があります。 作業用コピーの作成に IProblemRequestor が指定された場合、作業用コピーを問題検出と調整することができます。 これを行うには、reconcile メソッドを使用できます。以下に例を示します。

  ICompilationUnit unit = ..; // get some compilation unit
			
  // create requestor for accumulating discovered problems
  IProblemRequestor problemRequestor = new IProblemRequestor() {
    public void acceptProblem(IProblem problem) {
      System.out.println(problem.getID() + ": " + problem.getMessage());
    }
    public void beginReporting() {}
    public void endReporting() {}
    public boolean isActive() {	return true; } // will detect problems if active
  };
    
  // use working copy to hold source with error
  ICompilationUnit workingCopy = unit.getWorkingCopy(new WorkingCopyOwner() {}, problemRequestor, null);
  ((IOpenable)workingCopy).getBuffer().setContents("public class X extends Zork {}");

  // trigger reconciliation			
  workingCopy.reconcile(NO_AST, true, null, null);
acceptProblem(IProblem) メソッドで報告された問題について、アクションを追加することができます。 この例では、報告された問題は、Zork を解決できないか、または有効なスーパークラスではないということと、問題の ID が IProblem.SuperclassNotFound であるということです。

特記事項