-encoding and -source in module-info.java

Jesse Glick jesse.glick at oracle.com
Wed Jan 25 07:47:51 PST 2012


On 01/24/2012 08:08 PM, Alex Buckley wrote:
> Compilation units in the Java programming language consist of UTF-16 code units.

Of course. That is a character set, not an encoding.

> so does not belong in the Java SE platform's idea of a module declaration.

Perhaps not; theoretically a compiler could be loading sources out of a database that provides Unicode strings natively. But javac invoked from the command line always 
works on files, and these have a definite layout in the filesystem - including $root/module-info.java - and must have a specific encoding. This means that a directory 
tree representing sources for a Java module has an unambiguous meaning in the Java language only if something in that tree declares the encoding. That would suggest 
something like $root/encoding containing the (ASCII-encoded) name of the encoding.

Alternately, require modular Java sources to use a standard encoding, presumably UTF-8, as modern languages are tending to do.

> The API level available to a program can
> theoretically be "configured" by depending on a given version of java.base

(Or java.boot?) This is an interesting option newly available with Jigsaw - basically to tie the source level (and I suppose the target level) to that supported by the 
platform itself. This is a sensible enough default; the question is whether some modules may still need to

1. Use a newer source level than the platform supports, while using the supported target level. Historically this has worked in certain cases, where third-party libraries 
can fill in missing platform classes. Of course it cannot work in all or even most cases.

2. Use an older source level than the platform supports, whether using the recommended target level. Useful mainly in case new platform APIs are wanted, but a language 
change was incompatible for this module.

3. Use an older source level and an older target level. Useful in case the module must be able to run on the older platform, but can use a handful of new APIs where 
available (checked via reflection perhaps).

You are still left with the problem of a module which declares no explicit platform dependency: some default value must be used for the source level, and changing this 
default according to which version of javac happens to be used to compile it is a very bad idea.

> it's still up to a compiler to a) switch its language level to match the desired API

The main issue here would be whether it is possible to determine the version of java.base/boot/whatever being requested before knowing for sure what version of the 
language module-info.java is written in. If a new language spec radically changed how module versions are requested, it might be tricky to interpret the requires clauses 
unambiguously.

> b) switch its own use of platform classes to match the desired API

This issue at least would finally be addressed by modular javac: your module would compile against whatever platform API it requests, I hope downloading older platform 
modules on demand. In current Java projects it is generally impractical to pass -bootclasspath to a project with a CI-friendly build script - you would have to include a 
copy of the target JDK's rt.jar in versioned project sources - so generally this is not done, yet -source must be passed for predictability, so everyone using JDK 7 javac 
to compile gets the annoying warning mentioned in that blog. (Using -Xlint:-options is undesirable since then unrelated problems with javac options will be suppressed.)



More information about the jigsaw-dev mailing list