On 06/15/2017 09:07 PM, Pepper Lebeck-Jobe wrote:
*Question*
Why must the source files which make up a module be on the source path for
the module to be compiled?

There are a number of aspects to the answer for this.

First, some background.

It has been a decision of long standing that the module membership of a compilation unit is determined by the "host system", which in the case of command-line javac, means by the position of the file in the file system. The alternative, which was rejected early on, was to have to edit every single compilation unit in code that was being modularized to have a module declaration at the top, preceding the package declaration.

While it may seem to follow that for any compilation unit, you could just look in some appropriate enclosing directory to find the module declaration, there are some important use cases where that is not enough. Generally, these use cases are when the source for a module is spread across different directory hierarchies with different
directories for the package root. The two most common cases of this are when
some of the source for a module is generated, or when the source is a combination of some platform-independent code and some platform specific code. The ability to merge directory hierarchies like this is managed by using paths, as in source paths
or class paths.

Now, to some more specific reasons for the design decision.

First ... consistency. It has always been the case for Jigsaw javac that when compiling code from multiple modules together, all the source files given on the command line had to be present on the module source path .. meaning, on the source path for a module on the module source path. That was always required for the reasons described earlier, to be able to determine the module membership of each source file specified on the comment line. That was initially different from the case of compiling a single module, which initially was more like compiling "traditional" non-modular code. In time, it became clear that was a bad choice and it was better to have the compilation requirements for all modular code be more consistent, whether compiling one module or many.

Second ... to avoid obscure errors. In the initial design, when compiling a single module, javac tried to infer the module being compiled from the presence of a module declaration in a compilation unit specified on the command line, or on the source path or a module declaration on the class path. That led to the possibility of errors in which the module membership of a compilation unit specified on the command line (as determined by its position in the file system) could be different from the inferred module being compiled. For example, consider the case where the source path is empty, and the command line contains the source files for the module declaration for one module, and the class declarations for different module. There is no way, in that case, for javac to detect the misconfiguration and give a meaningful message. The solution was to require that when compiling modular code for a single module, all source files must appear on the source path so that javac can ensure that all sources files are part of the same module.


That all being said, I understand the concerns that this sets up the possibility of files being implicitly compiled when that is not desired, by virtue of being found on the source path. I also agree that -implicit:none is not an ideal solution to the issue. In time, we could consider a new option to better address the problem. In the meantime, the short term options are to either synthesize a suitable source directory with links, or to use the Compiler API to provide a custom file manager that
uses an equivalent synthetic source path.

-- Jon

Reply via email to