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

Paul Benedict pbenedict at apache.org
Tue Mar 15 18:25:49 UTC 2016


I am happy to say the latest EA only allows "module" or types. It is
either-or but not both.

Cheers,
Paul

On Tue, Mar 15, 2016 at 12:43 PM, Paul Benedict <pbenedict at apache.org>
wrote:

> 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