1

I have a project that I have been working on for a few days and I finally got it to compile cleanly. However, a git clone of the same remote branch (on the same machine, compiled in the same terminal instance) caused a compilation error. A fresh clone on a different machine had the same error. I figured it was an issue with my working directory having some additional untracked files, but I deleted all untracked files to the point where diff says the directories are identical except for things contained in the .git folder. I even checked permissions with tree and compared the resulting files with meld - they were basically identical, although a few source files had slightly different execution permissions.

The error was one that came from a file which I had excluded in the maven-compiler-plugin. This should essentially mean that the filename is never passed to javac, although I don't know exactly how it works under the hood. I realize that clearly the compiler is getting the file from somewhere if it is erroring on code inside it. In the one directory on my computer which worked, there are no errors and it compiles perfectly. On the other clones of the repo (which are, again, identical according to diff) it gives an error on this (excluded) file.

Additional experimentation showed that on a fresh git clone of the remote branch, a cp -R of the local directory, or a git clone of the local directory, compile failed. However, if I did a cp with the --archive option, the compile in the resulting directory succeeded. I narrowed it down to the --preserve=timestamps flag (which is enabled due to the fact that --archive is the same as -dR --preserve=all). If you didn't quite catch that, I'll say it again.

When I copy the directory normally, it refuses to compile properly. Only when the timestamps are preserved does it behave identically to the original directory.

I don't understand this - why does the java compiler (or maven) care about the timestamps?

4

1 に答える 1

1

この問題は、Maven コンパイラ プラグインの問題と、私が何かをしようとしていたという事実が組み合わさって、やや見当違いなものになりました。

簡単に言うと、コンパイラ プラグインは、コンパイルするすべてのファイルのリストと、ソース ディレクトリへのリンクを渡します。

ファイルのリストはまったく問題ありません。これは、javac がコンパイルするものを認識する方法だからです。ただし、ソース ディレクトリも渡されるという事実は理想的ではありません。ファイル (またはパターン) を Maven コンパイラ プラグインの<excludes>タグに入れると、javac に渡されるファイルのリストに表示されなくなります。ただし、ほとんどの場合、ソース ディレクトリ (maven が javac に渡すディレクトリ) に存在します。これは、これらのファイルを除外したとしても、必要に応じて javac がこれらのファイルをコンパイルできることを意味します。これは、ファイルの 1 つが別のファイルに依存している場合に発生することがあります。ここで予想される動作は、エラーをスローすることです。代わりに、除外されたファイルをコンパイルし、楽しい方法で続行します。

私の状況では(コメントで説明したように)、明示的に除外されたファイル(理由:mavenがクラスパスを処理する方法の無関係なバグは、mavenがファイルを適切にコンパイルできないことを意味します)がまだコンパイルしようとしていたため、問題が発生していました、コンパイル済みのバージョンのクラスを提供しようとしていたにもかかわらず。

この場合、タイムスタンプを保持せずにファイルをコピーすると、ソース ファイルが最近変更され、プリコンパイルされたクラスのバージョンが古くなっていると見なされました。そのため、javac は除外されたファイルをコンパイルしようとしました。タイムスタンプを保存したとき(ファイルが何ヶ月も変更されていないことを示していた)、 javac は代わりに提供された .class ファイルを使用する必要があることに気付きました。

于 2012-07-26T21:45:27.127 に答える