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

Alex Buckley alex.buckley at oracle.com
Mon Mar 21 18:10:26 UTC 2016


Imagine the 7.6 text about the host system wasn't there. Now the JLS has 
no rules about the name of the file from which a CompilationUnit 
production is parsed. A compiler is therefore allowed to reject a file 
named module-info.java whenever it wishes.

Now imagine the 7.6 text is put back. Since it allows the host system to 
choose when to follow it, it has no bearing on the previous paragraph.

Georgiy, I don't think it's productive to continue this thread further.

Alex

On 3/21/2016 6:44 AM, Georgiy Rakov wrote:
> According to my understanding import or type declarations are
> *optionally* followed by a type declaration according to the
> CompilationUnit grammar rule. JLS 7.6 just conditionally allows compiler
> to restrict file names to be aligned with type declaration but the
> compile errors are produced even if the condition is not met.
>
> Thanks,
> Georgiy.
>
> On 10.03.2016 1:02, Alex Buckley 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