Package, import and type declarations are allowed now in module-info.java by spec
Paul Benedict
pbenedict at apache.org
Tue Mar 15 17:43:29 UTC 2016
On Mon, Mar 14, 2016 at 5:21 PM, Alex Buckley <alex.buckley at oracle.com>
wrote:
> The JLS doesn't know what the string "module-info.class" means or what a
> "JAR root" is.
Of course. Though that wasn't my ultimate point; I was merely illustrating
(philosophically) why having "package" in module-info.java is nonsensical
syntax. A "package" statement doesn't mean anything useful in the context
of specifying module configuration. As far as I am aware, the module syntax
is meant to standalone in the file, but please correct me if you have other
intentions for the syntax. If you can also declare types, then a "package"
statement begins to make more sense -- but it would seem like a clumsy way
of doing things, which I wouldn't advocate (or allow syntactically).
Cheers,
Paul
> In 3/14/2016 9:08 AM, Paul Benedict wrote:
>
>> Alex, you wrote: "The JLS doesn't prevent javac from rejecting a package
>> declaration or an import declaration in a file called module-info.java."
>>
>> It seems that a package declaration, in this context, should be
>> prohibited syntax because module-info.class is always in the JAR root
>> which has no package.
>>
>> Cheers,
>> Paul
>>
>> On Wed, Mar 9, 2016 at 4:02 PM, Alex Buckley <alex.buckley at oracle.com
>> <mailto:alex.buckley at oracle.com>> wrote:
>>
>> The JLS doesn't prevent javac from rejecting a package declaration
>> or an import declaration in a file called module-info.java.
>>
>> In fact, since a package declaration or import declaration must be
>> followed by a type declaration, and since a type declaration cannot
>> use a hyphen, javac is free to take the optional rule from JLS 7.6
>> -- filename must align with type declaration -- and develop it
>> further: rejecting a package declaration or import declaration in
>> module-info.java because the filename cannot possibly align with any
>> type declaration.
>>
>> I can't speak to what a particular EA build of javac is doing with a
>> particular option. javac options are irrelevant to the JLS. If a
>> compiler accepts the Java language circa SE 9, then a module
>> declaration is a valid compilation unit. What's the name of the file
>> containing such a compilation unit? Anything the compiler likes.
>>
>> Alex
>>
>> On 3/9/2016 5:14 AM, Georgiy Rakov wrote:
>>
>> Hi Alex,
>>
>> if I understand correctly you mean about following assertions
>> from JLS 7.6:
>>
>> If and only if packages are stored in a file system (§7.2
>>
>> <
>> http://docs.oracle.com/javase/specs/jls/se8/html/jls-7.html#jls-7.2>),
>> the host system may choose to enforce the restriction that
>> it is a
>> compile-time error if a type is not found in a file under a
>> name
>> composed of the type name plus an extension (such as
>> |.java|or
>> |.jav|) if either of the following is true:
>>
>> *
>>
>> The type is referred to by code in other compilation
>> units of
>> the package in which the type is declared.
>>
>> *
>>
>> The type is declared |public|(and therefore is
>> potentially
>> accessible from code in other packages).
>>
>> Literally these assertion doesn't make presented behavior
>> corresponding
>> to spec because the declared type is neither public nor being
>> referred
>> to from other sources being compiled.
>>
>> Nevertheless following sources doesn't compile either despite
>> the fact
>> that no types are declared there at all.
>> Namely when only package is specified:
>>
>> mod\module-info.java:
>> module mod {
>> exports pkg;
>> }
>>
>> mod\pkg\module-info.java:
>> package pkg;
>>
>> then compiling it by following command line with javac from [2]:
>>
>> javac -modulesourcepath . mod\module-info.java
>> mod\pkg\module-info.java
>>
>> causes following output:
>>
>> mod\pkg\module-info.java:1: error: expected 'module
>> package pkg;
>> ^
>> 1 error
>>
>> When only import statment is specified:
>>
>> mod\module-info.java:
>> module mod {
>> exports pkg;
>> }
>>
>> mod\pkg\module-info.java:
>> import java.util.List;
>>
>> then compiling it by following command line with javac from [2]:
>>
>> javac -modulesourcepath . mod\module-info.java
>> mod\pkg\module-info.java
>>
>> causes following output:
>>
>> mod\pkg\module-info.java:1: error: expected 'module'
>> import java.util.List;
>> ^
>> 1 error
>>
>> Please see minimized test cases attached in tests23.zip. In order
>> to
>> reproduce, please:
>>
>> 1. Unzip the attached archive to some dir on Windows machined, say
>> directory A;
>> 2. Rename A\test2\test_bat to A\test2\test.bat and
>> A\test3\test_bat to
>> A\test3\test.bat;
>> 3. Modify these two test.bat files by changing JDK_HOME variable
>> to
>> point to your jigsaw JDK 9 installation directory;
>> 4. Run test.bat files in turn.
>>
>> BTW: javac behavior [2] currently differs depending on whether
>> sources
>> are compiled "in module" mode or not. By "module mode" I mean
>> specifying
>> modulesourcepath option. For instance without modulesourcepath
>> option
>> module declarations are not recognized as valid grammar while
>> import
>> declarations contained within module-info.java compile
>> successfully.
>> This can be seen by experimenting with test3 from the attached
>> testcases. Now javac from [2] even can throw exception in
>> "non-module"
>> mode, please see https://bugs.openjdk.java.net/browse/JDK-8150733
>> .
>>
>> Could you please tell if spec will specify somehow two modes of
>> processing java-sources, now it [1] doesn't.
>>
>> [1] http://cr.openjdk.java.net/~mr/jigsaw/spec/lang-vm.html
>> [2]
>>
>> http://download.java.net/java/jigsaw/archive/106/binaries/jigsaw-jdk-9-ea+106_windows-x86_bin.zip
>>
>> Thanks,
>> Georgiy.
>>
>> On 26.02.2016 21:26, Alex Buckley wrote:
>>
>> On 2/26/2016 8:37 AM, Georgiy Rakov wrote:
>>
>> current spec [1] now contains following assertions
>> related to grammar:
>>
>> A compilation unit (JLS 7.3) may contain a module
>> declaration, in
>> which case the filename of the compilation unit is
>> typically
>> |module-info.java|.
>>
>> CompilationUnit:
>> [PackageDeclaration] {ImportDeclaration}
>> {TypeDeclaration}
>> ModuleDeclaration
>>
>> These assertions allows to specify any of import,
>> package or type
>> declarations in any compilation unit, for instance
>> module-info.java is
>> allowed to contain any of the mentioned declarations.
>> However currently
>> javac in the latest jigsaw build [2] reports an error on
>> such cases
>> provided they are compiled in module mode. For example
>> if we have
>> following directory structure:
>>
>> mod\module-info.java:
>> module mod {
>> exports pkg;
>> }
>>
>> mod\pkg\module-info.java:
>> package pkg;
>>
>> class C {
>> }
>>
>> then compiling it by following command line with javac
>> from [2]:
>>
>> javac -modulesourcepath . mod\module-info.java
>> mod\pkg\module-info.java
>>
>> causes following output:
>>
>> mod\pkg\module-info.java:1: error: expected 'module'
>> package pkg;
>> ^
>> 1 error
>>
>>
>> javac is merely choosing to implement the rule at the end of
>> JLS 7.6
>> that a type declaration (optionally preceded by package/import
>> declarations) must be provided in a suitably named file.
>>
>> Perhaps I should say "a variant of the rule" because 7.6 as
>> written
>> concerns a public type and your example has a package-access
>> type.
>> Still, bottom line, javac is free to require that a
>> compilation unit
>> which starts with a package declaration _must not_ be in a
>> file called
>> foo-bar.java -- the hyphen indicates a name that can't
>> possibly align
>> with the type declared in the compilation unit.
>>
>> The error message for mod\pkg\module-info.java could be a
>> bit more
>> helpful, but that's a quality-of-implementation detail.
>>
>> Conversely, a compilation unit that contains a module
>> declaration
>> _may_ be in a file called module-info.java, or in a file
>> called
>> foo-bar.java, or in a file called mod_decl.JAV. The
>> "typically" in [1]
>> is meant to indicate that the sub-clause on filename is
>> non-normative.
>> This is akin to how a compilation unit that contains a
>> package-access
>> type declaration for class C _may_ be in a file D.java.
>>
>> Alex
>>
>>
>>
>>
More information about the jigsaw-dev
mailing list