Package, import and type declarations are allowed now in module-info.java by spec

Paul Benedict pbenedict at apache.org
Mon Mar 14 16:08:05 UTC 2016


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>
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