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