Discussion:
Package, import and type declarations are allowed now in module-info.java by spec
Georgiy Rakov
2016-02-26 16:37:11 UTC
Permalink
Hello,

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

The minimized testcase is attached; in order to run it please:

1. Unzip the attached archive to some dir on Windows machined, say
directory A;
2. Rename A\test\test_bat to A\test\test.bat;
3. Modify test.bat by changing JDK_HOME variable to point to your jigsaw
JDK 9 installation directory;
4. Run test.bat.

It seems to me either spec or implementation issue, could you please
tell if you agree.

[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.
Alex Buckley
2016-02-26 18:26:03 UTC
Permalink
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java mod\pkg\module-info.java
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
Georgiy Rakov
2016-03-09 13:14:54 UTC
Permalink
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.
Post by Alex Buckley
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Alex Buckley
2016-03-09 22:02:10 UTC
Permalink
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
Post by Georgiy Rakov
Hi Alex,
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java mod\pkg\module-info.java
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
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.
Post by Alex Buckley
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Paul Benedict
2016-03-14 16:08:05 UTC
Permalink
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
Post by Alex Buckley
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
Post by Georgiy Rakov
Hi Alex,
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
Post by Alex Buckley
),
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
Post by Alex Buckley
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Alex Buckley
2016-03-14 22:21:14 UTC
Permalink
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
Post by Paul Benedict
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
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
Hi Alex,
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
current spec [1] now contains following assertions
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
then compiling it by following command line with javac
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Paul Benedict
2016-03-15 17:43:29 UTC
Permalink
Post by Alex Buckley
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
Post by Alex Buckley
Post by Paul Benedict
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
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
Hi Alex,
if I understand correctly you mean about following assertions
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
current spec [1] now contains following assertions
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
then compiling it by following command line with javac
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Paul Benedict
2016-03-15 18:25:49 UTC
Permalink
I am happy to say the latest EA only allows "module" or types. It is
either-or but not both.

Cheers,
Paul
Post by Paul Benedict
Post by Alex Buckley
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
Post by Alex Buckley
Post by Paul Benedict
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
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
Hi Alex,
if I understand correctly you mean about following assertions
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
current spec [1] now contains following assertions
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
then compiling it by following command line with javac
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Georgiy Rakov
2016-03-21 13:44:31 UTC
Permalink
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.
Post by Alex Buckley
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 --
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
Post by Georgiy Rakov
Hi Alex,
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
Post by Alex Buckley
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Alex Buckley
2016-03-21 18:10:26 UTC
Permalink
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
Post by Georgiy Rakov
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.
Post by Alex Buckley
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 --
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
Post by Georgiy Rakov
Hi Alex,
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
*
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.
module mod {
exports pkg;
}
package pkg;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
mod\pkg\module-info.java:1: error: expected 'module
package pkg;
^
1 error
module mod {
exports pkg;
}
import java.util.List;
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
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.
Post by Alex Buckley
Post by Georgiy Rakov
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|.
[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
module mod {
exports pkg;
}
package pkg;
class C {
}
javac -modulesourcepath . mod\module-info.java
mod\pkg\module-info.java
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
Loading...