-encoding and -source in module-info.java
Jesse Glick
jesse.glick at oracle.com
Wed Jan 25 16:52:43 PST 2012
On 01/25/2012 06:36 PM, Peter Jensen wrote:
> A Java compiler may support different encodings
The Java platform specifies a minimum set of encodings which are guaranteed to be supported, so I would expect that these would be guaranteed for source file encoding
too. Whether it is prudent to permit a source tree to use an "optional" encoding, i.e. whether a compiler implemented in the JVM should support any extra encoding that
JVM actually supports, is another question.
> it may support compilation of source code written against different version of the JLS
That is why I recommended that the source level be physically declared in the source root. (Whether in module-info.java itself or in some other standardized place does
not make much practical difference, so long as either the JLS or the javac tool docs specify it.)
> Specifying such options, in whatever format, means specifying common capabilities where it has previously been open to the implementation.
-encoding and -source at least are considered "standard" options (not -X prefixed). Anyway a (file-based) compiler could not work at all unless it knew what the values of
these two fundamental parameters were: they are intrinsic properties of the sources themselves.
> [is this] especially critical for modules? Or is it more a matter of filling an existing void?
There is an existing void. The reason I bring this up in the context of Jigsaw is that in JDK 7 and earlier, a naked source tree could not be analyzed in any very useful
way at all because you would lack any information about its expected classpath: even if you optimistically guessed at encoding (ISO-8859-1?) and source level (1.7?), you
would get no further than a syntax parse. Even a wildcard import would be impossible to interpret. So in the existing language, any tool which wants to work with a source
tree at more than a superficial level - an IDE, a static analyzer, HTMLized code browser, structural grep, etc. - really has to be supplied a bunch of metadata (*) to
make any sense of it, especially a classpath. Given that, you might as well throw in an encoding and source level at the same time.
By contrast, under the current Jigsaw design a tool could get complete "classpath" information (**) right from $basedir/module-info.java (***), making it possible for the
first time to be run without any configuration beyond the location of the source root (or a file within that root) - but only if the encoding and source level can also be
obtained. It would seem a pity to have almost, but not quite, self-describing module sources in JDK 8.
My recent post about migrating -processorpath to module-info.java is on the same topic. While there are some processors which are elective for a given module - a
programmer or CI build might run them on some occasions or might not - many processors are integral to the function of a library used by the module. The processor might
perform mandatory semantic error checks, without which an IDE or refactoring tool would be unaware that it was about to make an invalid change. More critically, the
processor might generate Java sources which are required for regular project sources to compile - so without knowledge of which processors are expected to be run by
javac, a source-based tool would be left with unexplained missing symbols.
Those javac options which could be freely changed for a given source tree without really affecting the meaning of the input, such as -g or -Xmaxerrs or -Xprefer:source,
are irrelevant to source-based tools and do not belong in portable source metadata. How -target should be treated is debatable. -Xlint suboptions are a grey area in
between intrinsic and incidental attributes - a given module may be tuned to be "lint-free" for certain classes of warning only - so it would be nice if @SuppressWarnings
could be specified in module-info.java and considered to apply to all compilation units in the module (meaning it is OK to use -Xlint:all).
(*) Or be embedded in or otherwise integrated with Maven, which is the only broadly accepted metadata for Java sources today. While reading maven-compiler-plugin
parameters is cumbersome, it at least can be done pretty reliably. Script-oriented build tools (Ant, Gradle, ...) are more or less opaque to a tool which wants to know
how javac would have been invoked, and parsing proprietary project metadata from all popular IDEs would be challenging.
(**) At least a list of required module names and baseline versions, which can be translated to the equivalent of a classpath if those dependencies can be located
somehow. Assuming they must be present in the local cache repository (or in a preregistered remote repository) in order for javac to work, then any tool running on the
same machine could find them too.
(***) The same argument applies if module metadata were to be in some other format - XML, manifest, etc. - so long as javac mandates that this be physically located in a
specific place in the source tree, rather than referred to with a CLI option.
More information about the jigsaw-dev
mailing list