RFR: 8296656: java.lang.NoClassDefFoundError exception on running fully legitimate code [v7]

Vicente Romero vromero at openjdk.org
Mon Mar 27 20:08:46 UTC 2023


On Sat, 25 Mar 2023 22:08:23 GMT, Archie L. Cobbs <duke at openjdk.org> wrote:

>> This bug and a few others fall into the "output file clash" bucket. This is when the compiler thinks it's writing out two separate files, but due to the way the O/S filesystem maps `Path`'s to actual files, it's really writing the same file twice.
>> 
>> This is usually due to case-insensitive filesystems, but can also be due to how a filesystem "normalizes" file names. For example, on MacOS, compiling this class will generate such a clash:
>> 
>> public class Test {
>>     interface Cafe\u0301 {
>>     }
>>     interface Caf\u00e9 {
>>     }
>> }
>> 
>> The reason is that `\u0301` is the Unicode character "Combining Acute Accent" which means "stick an accent over the previous character". So MacOS normalizes a `e` followed by a `\u0301` into a Unicode `\u00e9`, that is, `é`. However, the Java language treats these the two names `Cafe\u0301` and `Caf\u00e9` as distinct.
>> 
>> It's infeasible to truly "fix" this problem, so we resort here to a salve, which is to add a new compiler flag `--detect-output-file-clashes` that enables detection of output file clashes. When the flag is enabled, and a clash is detected, an error is immediately thrown. For example, compiling the example above gives this:
>> 
>> $ javac --help-extra
>>   ...
>>   --detect-output-file-clashes
>>         Generate an error if any output file is overwritten during compilation. This can occur, for example,
>>         on case-insensitive filesystems. This applies to class files, native header files, and source files.
>>   ...
>> $ javac --detect-output-file-clashes Test.java
>> Test.java:4: error: error while writing Café: output file clash: /Users/archie/test/Test$Café.class
>>     interface Caf\u00e9 {
>>     ^
>> 1 error
>> 
>> This at least gives people at risk of encountering this problem a way to turn a runtime error into a compile-time error.
>> 
>> **Outstanding Questions**
>> * Is making this optional via an (extended) flag `--detect-output-file-clashes` the best way to address this?
>> * Does the new field `BaseFileManager.outputFilesWritten` ever need to be cleared? Can the file manager be used for multiple compilations? If so, is there some "reset" step we should hook into?
>
> Archie L. Cobbs has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Add "compiler.warn.output.file.clash" to message example exclusion file.

tier1-4 green

-------------

PR Comment: https://git.openjdk.org/jdk/pull/12754#issuecomment-1485792340


More information about the compiler-dev mailing list