Explicitly empty sourcepath regression
Jonathan Gibbons
jonathan.gibbons at oracle.com
Sun Jun 18 16:19:42 UTC 2017
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
More information about the jigsaw-dev
mailing list