Почему java (maven) заботится о временных метках файлов во время компиляции?

У меня есть проект, над которым я работал несколько дней, и наконец-то я смог его скомпилировать. Однако клон git той же удаленной ветки (на той же машине, скомпилированный в том же экземпляре терминала) вызвал ошибку компиляции. У свежего клона на другой машине была та же ошибка. Я решил, что проблема в том, что в моем рабочем каталоге есть дополнительные неотслеживаемые файлы, но я удалил все неотслеживаемые файлы до точки, где diff говорит, что каталоги идентичны, за исключением вещей, содержащихся в папке .git. Я даже проверил разрешения с помощью tree и сравнил полученные файлы с meld — они были в основном идентичными, хотя несколько исходных файлов имели немного разные разрешения на выполнение.

Ошибка возникла из-за файла, который я исключил в плагине maven-compiler-plugin. Это должно по сути означать, что имя файла никогда не передается в javac, хотя я точно не знаю, как это работает внутри. Я понимаю, что явно компилятор получает файл откуда-то, если он ошибается в коде внутри него. В той директории на моем компе, которая работала, ошибок нет и компилируется отлично. На других клонах репо (которые опять же идентичны по diff) выдает ошибку на этом (исключенном) файле.

Дополнительные эксперименты показали, что на новой git clone удаленной ветке, cp -R локального каталога или git clone локального каталога не удалось выполнить компиляцию. Однако, если я выполнил cp с параметром --archive, компиляция в результирующем каталоге успешна. Я сузил его до флага --preserve=timestamps (который включен из-за того, что --archive совпадает с -dR --preserve=all). Если вы не совсем уловили это, я повторю еще раз.

Когда я обычно копирую каталог, он отказывается правильно компилироваться. Только когда временные метки сохранены, он ведет себя так же, как исходный каталог.

Я этого не понимаю - почему компилятор java (или maven) заботится о временных метках?


person matt5784    schedule 05.07.2012    source источник
comment
Ant/Maven (как и make в средах, отличных от Java) зависят от меток времени, чтобы определить, устарел ли файл и нуждается ли он в перекомпиляции. В: Единственная проблема в том, что вещи перестраиваются? Или за вашим вопросом стоит другая, более серьезная проблема? В: В чем именно является проблема?   -  person paulsm4    schedule 06.07.2012
comment
У меня есть исключение в конфигурации плагина maven-compiler. В работающих каталогах исключение работает. В каталогах, которые этого не делают, исключение также КАЖЕТСЯ работать (говорит, что оно компилирует одинаковое количество исходных папок, аргумент -sourcepath javac имеет такое же количество файловых аргументов и НЕ включает плохой файл), но это дает мне ошибка компиляции в исключенном файле.   -  person matt5784    schedule 06.07.2012
comment
Почему у вас есть файлы, которые не должны компилироваться в ваших папках? Просто удалите их, потому что их можно восстановить через VCS. Используете ли вы значения по умолчанию src/main/java для Maven?   -  person khmarbaise    schedule 06.07.2012
comment
Кстати: Вы сделали mvn чистый пакет? Какую версию плагина компилятора вы используете?   -  person khmarbaise    schedule 06.07.2012
comment
Ну конечно; естественно. Думаю, в процессе я сделал около сотни mvn clean; mvn package. Я тестировал как 2.4, так и 2.5 плагина. Файлы ДОЛЖНЫ быть скомпилированы, но из-за несвязанной ошибки maven не может сделать это должным образом (см. the-classpath-during-maven-android-build" title="базовые классы Java все еще находятся в пути к классам во время сборки maven android">stackoverflow.com/questions/11250352/), поэтому мне нужно реализовать один из несколько довольно ужасных обходных путей для правильной компиляции. Не используя src/main/java, все еще есть /src/com/example... (тесты в другом месте). В процессе перехода с ant на maven.   -  person matt5784    schedule 06.07.2012


Ответы (1)


Проблема оказалась в плагине компилятора Maven в сочетании с тем фактом, что я пытался сделать что-то несколько ошибочное.

Вкратце, подключаемый модуль компилятора передает список всех файлов, которые вы хотите скомпилировать, а также ссылку на исходный каталог.

Со списком файлов все в порядке, так как именно так javac знает, что компилировать. Однако тот факт, что исходный каталог также передается, не идеален. Когда вы помещаете файл (или шаблон) в тег <excludes> подключаемого модуля компилятора maven, он больше не будет отображаться в списке файлов, переданных в javac. Однако он, скорее всего, будет находиться в вашем исходном каталоге (который maven передает javac). Это означает, что javac все еще может скомпилировать эти файлы, если захочет, даже если вы их исключили. Это может произойти, если один из файлов является зависимостью другого. Ожидаемым поведением здесь было бы выдать ошибку — вместо этого он компилирует исключенный файл и продолжает свой веселый путь.

В моей ситуации (как я объяснил в комментариях) у меня были проблемы, потому что файл, который был явно исключен (причина: несвязанная ошибка в том, как maven обрабатывает пути к классам, означает, что файл не может быть правильно скомпилирован maven) все еще пытался скомпилировать , хотя я пытался предоставить предварительно скомпилированную версию класса.

В этом случае, если я скопировал файлы без сохранения временных меток, он подумал, что исходные файлы были недавно изменены и что предварительно скомпилированная версия класса устарела. Поэтому javac попытался скомпилировать исключенный файл. Только когда я сохранил временные метки (которые показывали, что файл не изменялся в течение нескольких месяцев), javac понял, что вместо этого следует использовать предоставленный файл .class.

person matt5784    schedule 26.07.2012
comment
Кроме того, в исходном пути не должно быть файлов, которые никогда не следует компилировать. - person Paŭlo Ebermann; 12.04.2013
comment
Что, если у меня есть разные цели сборки, и иногда я хочу построить определенные части, а иногда я хочу построить другие части? Существует множество ситуаций, когда у вас может легко оказаться код в исходном пути, который вы не хотите компилировать, по крайней мере время от времени. Я подробно описываю проблему с функцией системы, и ваше решение — Не использовать эту функцию. Это не конструктивно и не полезно. - person matt5784; 17.04.2013