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

Alex Buckley alex.buckley at oracle.com
Mon Mar 14 22:21:14 UTC 2016


The JLS doesn't know what the string "module-info.class" means or what a 
"JAR root" is. It only knows about Unicode input matching the 
CompilationUnit production. Nothing is mandated about the filesystem 
layout of files containing CompilationUnit productions that include a 
PackageDeclaration. For clarity, we could extend 7.6's compiler guidance 
to cover a file called module-info.java, but technically the guidance is 
already broad enough to allow a compiler to "do the right thing".

Alex

On 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