特定の順序でソースを指定すると、一部の Java 1.6 ソースが Maven でコンパイルされず、javac でのみコンパイルされる状況があります。
pom.xml は必要最小限ですが、1.6 を指定-source
します。-target
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
ComputeOperation.java
package test.domain;
public interface ComputeOperation<T> {
public T compute(T arg1, T arg2);
}
計算.java
package test.domain;
public enum Computations implements ComputeOperation<Integer> {
ADD {
@Override
public Integer compute(Integer arg1, Integer arg2) {
return arg1 + arg2;
}
},
SUBTRACT {
@Override
public Integer compute(Integer arg1, Integer arg2) {
return arg1 - arg2;
}
}
}
App.java
package test.app;
import test.domain.*;
public class App {
public static void main( String[] args ) {
System.out.println(Computations.ADD.compute(1, 1));
}
}
Maven ビルドは次のように失敗します (完全なデバッグ ログはこちら)。
[ERROR] COMPILATION ERROR :
[INFO] -------------------------------------------------------------
[ERROR] /home/nzucker/projects/maven-test/src/main/java/test/app/App.java:[7,44] cannot find symbol
symbol : method compute(int,int)
location: class test.domain.Computations
[INFO] 1 error
javac
App.java が Computations.java の前にある場合、Plain oldコンパイルは成功しません。
[nzucker:maven-test]$ javac -source 1.6 -target 1.6 -g -d target/classes src/main/java/test/app/App.java src/main/java/test/domain/Computations.java src/main/java/test/domain/ComputeOperation.java
src/main/java/test/app/App.java:7: cannot find symbol
symbol : method compute(int,int)
location: class test.domain.Computations
System.out.println(Computations.ADD.compute(1, 1));
^
1 error
しかし、App.java を入力ソースの最後に配置すると、ビルドは成功します。
[nzucker:maven-test]$ javac -source 1.6 -target 1.6 -g -d target/classes src/main/java/test/domain/Computations.java src/main/java/test/domain/ComputeOperation.java src/main/java/test/app/App.java
[nzucker:maven-test]$ java -cp target/classes/ test.app.App
2
最後に、import
App.java を静的インポートに変更すると、コンパイルは成功します。
package test.app;
import static test.domain.Computations.*;
public class App {
public static void main( String[] args ) {
System.out.println(ADD.compute(1, 1));
}
}
質問:
「maven の javac コンパイル順序バグの回避策」を認識しています。これは Maven の真の欠陥ですか? もしそうなら、JIRAの問題は何ですか?
また、コンパイルが失敗するのはなぜですか? javac は、前処理段階でクラス間の依存関係とコンパイル順序を解決すると思いましたか? 私は間違っていたと思いますか?これをカバーする仕様はありますか?
OK、私がリンクした他の質問には、Java 1.6 のバグを指摘する回答があります。答えは、Java 1.7 にアップグレードするか、回避策を実装することです。