maven中javac编译命令错误的解决方法

Ben*_*rdy 19 java javac maven

我遇到了Java编译器中的一个错误,其中提交用于编译的文件的顺序可能导致代码无法编译.我已经深入研究了代码,以找出我能够重现问题的最少量代码,从而产生三个源文件(每个1个类).

public interface ActionSpec {
    public abstract int run(String param);
}


public enum Actions implements ActionSpec {
    SKIP {
        public int run(String d) {
            return 0;
        }
    };
}

public class Program {

    public static void main(String[] args) {
        Actions.SKIP.run("hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

通过以特定顺序使用javac参数可以重现该问题.简而言之,为了成功,必须始终在使用它的Program类之前编译Actions类,否则javac无法以理智的方式处理它:

# this case fails
echo "Trying order: javac Program.java Actions.java ActionSpec.java"
rm *class
javac -verbose Program.java Actions.java ActionSpec.java

# this case fails
#rm *class
#javac Program.java Actions.java ActionSpec.java

# this case fails
#rm *class
#javac ActionSpec.java Program.java Actions.java

# this case succeeds
#rm *class
#javac ActionSpec.java Actions.java Program.java

# this case succeeds
#rm *class
#javac Actions.java ActionSpec.java Program.java

# this case succeeds
#rm *class
#javac Actions.java Program.java ActionSpec.java
Run Code Online (Sandbox Code Playgroud)

编译错误发生时始终是相同的 - 即使它们都实现了具有该run方法的接口,也无法找到Actions枚举实例上的run方法.

Program.java:6: cannot find symbol
symbol  : method run(java.lang.String)
location: class problem.Actions
        Actions.SKIP.run("hello");
Run Code Online (Sandbox Code Playgroud)

该错误似乎与甲骨文网站上报道的这个错误有关.我在mac os x 10.7.2 x86_64上使用javac 1.6.0_29,但也在Linux上重现了它.

当我使用Maven构建时,这个问题变得明显,并且似乎没有任何控制编译的顺序.因此,我正在寻找一种解决方法,要么强制maven以这样的顺序编译文件以避免这种编译器错误,要么摆弄编译器标志(或类似的东西)以避免它.问题出现在工作站和持续集成环境中,所以它必须全面工作.有什么建议?

编辑:刚刚尝试了以下解决方法,尽管只是将有问题的枚举分配给它实现的接口类型的变量,但令人惊讶地导致错误消失.

public class Program {

    public static void main(String[] args) {
        ActionSpec a = Actions.SKIP;
        a.run("hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

仍对其他人的意见感兴趣.

Kon*_*uda 5

我玩了,发现添加简单的演员:

public static void main(String[] args) {
    ((ActionSpec)Actions.SKIP).run("hello");
}
Run Code Online (Sandbox Code Playgroud)

解决了这个问题.将此枚举作为方法参数作为接口传递也可以解决问题