Обходной путь для ошибки порядка компиляции 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");
    }
}

Проблема воспроизводится, если аргументы javac расположены в определенном порядке. Короче говоря, для достижения успеха класс Actions всегда должен компилироваться перед классом Program, который его использует, иначе 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

Ошибка компиляции, когда она возникает, всегда является то же самое - метод запуска в экземплярах перечисления Действия не может быть найден, даже если все они реализуют интерфейс, имеющий этот метод выполнения.

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

Похоже, ошибка связана с , о которой сообщалось на сайте Oracle . Я использую javac 1.6.0_29 в Mac OS X 10.7.2 x86_64, но также воспроизвел его в Linux.

Эта проблема стала очевидной, когда я использую Maven для сборки и, похоже, не могу контролировать порядок компиляции. Поэтому я ищу обходной путь, чтобы заставить maven компилировать файлы в таком порядке, чтобы избежать этой ошибки компилятора, или возиться с флагами компилятора (или что-то в этом роде), чтобы избежать этого.Проблема возникает как на рабочих станциях, так и в средах непрерывной интеграции, поэтому она должна работать повсеместно. Есть предложения?

РЕДАКТИРОВАТЬ: Просто попробовал следующий обходной путь, который, несмотря на простое присвоение рассматриваемого перечисления переменной с типом реализуемого интерфейса, неожиданно приводит к исчезновению ошибки.

public class Program {

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

Все еще интересуются мнениями других.

19
задан Ben Hardy 29 February 2012 в 21:16
поделиться