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);

バッチ・コンパイラーの使用

バッチ・コンパイラーの検索

バッチ・コンパイラー・クラスは、JDT/コア・プラグインの内部クラスに配置されています。 そのため、ディレクトリー plugins/org.eclipse.jdt.corejdtcore.jar ファイル内にあります。 クラスの名前は、org.eclipse.jdt.internal.compiler.batch.Main です。

バッチ・コンパイラーの実行

使用可能なオプション

背景がオレンジ色の箇所が、推奨のオプションです。

名前 使用法
クラスパス・オプション
-bootclasspath <dir 1>;<dir 2>;...;<dir P> これは、コンパイラーにより使用されるクラス・ファイルのブートストラップに使用されるディレクトリーまたは JAR ファイルのリストです。 デフォルトで、実行中の VM のライブラリーが使用されます。 エントリーは、プラットフォームのパス分離文字により分離されます。
-cp
-classpath <dir 1>;<dir 2>;...;<dir P>
これは、ソース・ファイルのコンパイルに使用されるディレクトリーまたは JAR ファイルのリストです。 デフォルト値は、プロパティー "java.class.path" の値です。 エントリーは、プラットフォームのパス分離文字により分離されます。
-extdirs <dir 1>;<dir 2>;...;<dir P> これは、拡張 ZIP/JAR ファイルの場所の指定に使用されるディレクトリーのリストです。 エントリーは、プラットフォームのパス分離文字により分離されます。
-sourcepath <dir 1>;<dir 2>;...;<dir P> ソース・ファイルの指定に使用されるディレクトリーのリストです。 エントリーは、プラットフォームのパス分離文字により分離されます。
-d <dir 1>|none これは、生成された .class ファイルがダンプされるディレクトリーの指定に使用されます。 省略された場合、パッケージのディレクトリー構造は作成されません。
.class ファイルを生成しない場合は、-d none を使用してください。
-encoding <encoding name> デフォルトのソース・エンコード・フォーマットを指定します (それぞれの入力ソース・ファイル/フォルダー名に [encoding <encoding name>] のサフィックスを付けることにより、ファイルごとの原則でカスタム・エンコードを指定することもできます)。
準拠オプション
-target 1.1|1.2|1.3|1.4|1.5|5|5.0 .class ファイルのターゲット設定を指定します。 指定可能な値は以下のとおりです。
  • 1.1 (メジャー・バージョン: 45 マイナー: 3)
  • 1.2 (メジャー・バージョン: 46 マイナー: 0)
  • 1.3 (メジャー・バージョン: 47 マイナー: 0)
  • 1.4 (メジャー・バージョン: 48 マイナー: 0)
  • 1.5, 5 または 5.0 (メジャー・バージョン: 49 マイナー: 0)
デフォルトは以下のとおりです。
  • 1.1-1.3 モードの場合
  • 1.2-1.4 モードの場合
  • 1.5-1.5 モードの場合
-1.3 準拠レベルを 1.3 に設定します。-source 1.3 -target 1.1 を暗黙的に設定します。
-1.4 準拠レベルを 1.4 に設定します (デフォルト)。-source 1.3 -target 1.2 を暗黙的に設定します。
-1.5 準拠レベルを 1.5 に設定します。-source 1.5 -target 1.5 を暗黙的に設定します。
-source 1.3|1.4|1.5|5|5.0 コンパイラーのソース・レベルを使用可能に設定するために使用されます。
指定可能な値は以下のとおりです。
  • 1.3
  • 1.4
  • 1.55 または 5.0
デフォルトは以下のとおりです。
  • 1.3-1.3 モードの場合
  • 1.4-1.4 モードの場合
  • 1.5-1.5 モードの場合
1.4 では、assert がキーワードとみなされます。1.5 では、enum および assert がキーワードとみなされます。
警告オプション
-warn:
allDeprecation
allJavadoc
assertIdentifier
boxing
charConcat
conditionAssign
constructorName
dep-ann
deprecation
emptyBlock
enumSwitch
fieldHiding
finalBound
finally
hiding
incomplete-switch
indirectStatic
intfAnnotation
intfNonInherited
javadoc
localHiding
maskedCatchBlocks
nls
noEffectAssign
null
over-ann
pkgDefaultMethod
semicolon
serial
specialParamHiding
static-access
staticReceiver
suppress
synthetic-access
syntheticAccess
tasks(<task1>|...|<taskN>)
typeHiding
unchecked
unnecessaryElse
unqualified-field-access
unqualifiedField
uselessTypeCheck
unused
unusedArgument
unusedImport
unusedLocal
unusedPrivate
unusedThrown
varargsCast
warningToken
警告レベルを設定します。
例: -warn:unusedLocals,deprecation

赤色 の部分はデフォルトの設定値です。

    -warn:<, で区切られた警告>    リストされた警告のみを使用可能にします
    -warn:+<, で区切られた警告>   追加の警告を使用可能にします
    -warn:-<, で区切られた警告>   指定された警告を使用不可にします
allDeprecation 使用されないコード内でも使用すべきではない
allJavadoc javadoc が無効または欠落
assertIdentifier 識別子として使用された assert の発生
boxing オートボクシング型変換
charConcat 文字配列が文字列に明示的に変換されることなく、文字列の連結で使用された場合
conditionAssign 考えられる不慮のブール値の代入
constructorName コンストラクター名を持つメソッド
dep-ann @Deprecated 注釈の欠落
deprecation 使用すべきでないコード外部での使用すべきでないタイプまたはメンバーの使用
emptyBlock 文書化されていない空のブロック
enumSwitch、
incomplete-switch
不完全な列挙スイッチ
fieldHiding 別の変数が非表示のフィールド
finalBound 最終バウンドがあるタイプ・パラメーター
finally 正常に完了していない finally ブロック
hiding fieldHiding、localHiding、typeHiding および maskedCatchBlock のマクロ
indirectStatic 静的メンバーへの間接参照
intfAnnotation スーパー・インターフェースとして使用される注釈タイプ
intfNonInherited インターフェースを継承しないメソッドの互換性
javadoc 無効な javadoc
localHiding 別の変数が非表示のローカル変数
maskedCatchBlocks 隠れた catch ブロック
nls 非 nls の文字列リテラル (タグ //$NON-NLS-<n> が欠如)
noEffectAssign 効果のない代入の場合
null NULL 検査が欠落または冗長
over-ann @Override 注釈の欠落
pkgDefaultMethod パッケージのデフォルト・メソッドを無効にする試行
serial serialVersionUID の欠落
semicolon 不要なセミコロンまたは空のステートメント
specialParamHiding 別のフィールドが非表示のコンストラクターまたはセッター・パラメーター
static-access indirectStatic および staticReceiver のマクロ
staticReceiver 静的フィールドの取得または静的メソッドの呼び出しに、静的ではない受信側が使用された場合
suppress @SuppressWarnings を使用可能にする
syntheticAccess、
synthetic-access
内部クラスに対して合成アクセスを実行する場合
tasks ソース・コード内でのタスク・タグのサポートを可能にする
typeHiding 別のタイプが非表示のタイプ・パラメーター
unchecked 未検査の型操作
unnecessaryElse 不要な ELSE 節
unqualified-field-access、
unqualifiedField
フィールドへの非修飾参照
unused unusedArgument、unusedImport、unusedLocal、unusedPrivate および unusedThrown のマクロ
unusedArgument 未使用のメソッド引数
unusedImport 未使用のインポート参照
unusedLocal 未使用のローカル変数
unusedPrivate 未使用の private メンバー宣言
unusedThrown 未使用で宣言済みのスローされた例外
uselessTypeCheck 不要な cast/instanceof 演算命令
varargsCast 可変引数に明示的なキャストが必要
warningToken @SuppressWarningsb の未処理の警告トークン

-nowarn 警告なし (-warn:none と同等)
-deprecation -warn:deprecation と同等
デバッグ・オプション
-g[:none|:lines,vars,source] デバッグの属性レベルを設定します
-g すべてのデバッグ情報 (-g:lines,vars,source と同等)
-g:none デバッグ情報なし
-g:[lines,vars,source] 選択的なデバッグ情報
-preserveAllLocals すべてのローカル変数を保持することをコンパイラーに明示的に要求 (デバッグの目的)。 省略した場合、コンパイラーは未使用のローカル変数を除去します。
拡張オプション
@<file> ファイルからコマンド行の引数を読み取ります
-maxProblems <n> コンパイル単位ごとの問題の最大数 (デフォルトは 100)
-log <filename> コンパイラーからのすべての出力がダンプされるログ・ファイルを指定します。 これは、バッチ・コンパイラーをデバッグする場合や、バッチのビルドからすべてのエラーおよび警告が含まれたファイルを取得する場合、非常に役に立ちます。 拡張子が .xml である場合、生成されたログは XML ファイルです。
-proceedOnError エラー時にコンパイルを継続し、問題のメソッドまたはタイプがあるクラス・ファイルをダンプします。 これが推奨されるのは、エラーが残っていてもそのアプリケーションを実行する必要がある場合のみです。
-verbose コンソールまたはログ・ファイル (指定された場合) に、アクセス/処理されたコンパイル単位を出力します
-referenceInfo 参照情報を計算します。 これは、ビルダーに接続されている場合にのみ有用です。 それ以外の場合、参照情報は役に立ちません。
-progress 進行を表示します (-log モード時のみ)
-time 速度情報を表示します
-noExit コンパイルの最後に System.exit(n) を呼び出しません (エラーがない場合は n=0)
-repeat <n> コンパイル処理を <n> 回繰り返します (パフォーマンス分析)。
-inlineJSR インライン JSR バイトコード (target >= 1.5 の場合の暗黙)
-enableJavadoc javadoc 内部の参照を考慮します
ヘルプ・オプション
-? -help ヘルプ・メッセージを表示します
-v -version コンパイラーのビルド番号を表示します。 これは、バグを報告する場合に非常に有用です。
-showversion コンパイラーのビルド番号を表示し、継続します。 これは、バグを報告する場合に非常に有用です。

d:¥temp -classpath rt.jar -time -g -d d:/tmp d:¥temp およびそのサブフォルダー内のすべてのソース・ファイルをコンパイルします。 クラスパスは、単に rt.jar です。 すべてのデバッグ属性を生成し、生成されたすべての .class ファイルが d:¥tmp にダンプされます。 コンパイラーの速度は、バッチ・プロセスの完了後に表示されます。
d:¥temp¥Test.java -classpath d:¥temp;rt.jar -g:none Test.java のみをコンパイルし、d:¥temp から依存するすべてのファイルを取得します。 クラスパスは rt.jar および d:¥temp であり、必要なすべてのクラスが、最初に d:¥temp、次に rt.jar で検索されます。 デバッグ属性は生成されず、生成されたすべての .class ファイルが d:¥tmp にダンプされます。

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.6.5 までのバージョンをサポートしています。

1.5.0 より後のバージョンを使用している場合は、コンパイラー固有のオプション指定に、ネストされたコンパイラー引数エレメントを使用できます。

...
<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>
    <compilerarg compiler="org.eclipse.jdt.core.JDTCompilerAdapter" line="-1.5 -warn:+boxing"/>
</javac>		
...

コンパイラーに依存するスクリプトの取得を避けるため、org.eclipse.jdt.core.JDTCompilerAdapter に設定したコンパイラー引数を使用することが推奨されます。 これが設定されない場合、そのスクリプトは Eclipse コンパイラーでのみ使用可能です。 設定されると、build.compiler プロパティーによって指定されたコンパイラー名と名前が異なる場合に、ネストされたコンパイラー引数は無視されます。

問題判別

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 であるということです。