Recently I've found out that if a package inside a module contains public interfaces or classes they are being exported automatically and hence unintentionally visible outside the module in case when recipient code is not modularized.
Structure of the project is as follows
parent
sub-donor (java-module)
my/project/first
Cowboy.java
module-info.java
sub-recipient (has no module-info)
my/project/somewhere
Main.java
module-info.java
module my.donor {
// nothing is exported here
}
Cowboy.java
public class Cowboy {
public String say() { return "eee-ha"; }
}
Main.java
import my.project.first.Cowboy;
public class Main {
public static void main(String[] args) {
Cowboy g = new Cowboy();
System.out.println(g.say());
}
}
The class from my.project.first
package is supposed to be used in my.donor
module only and be invisible outside the module.
Unexpectedly it is visible outside the module as if there were an exports my.project.first;
line, so the class Main
can be compiled.
The way to restrict visibility is to make sub-recipient
a java module, adding module-info.java
, then everything inside of sub-donor
becomes hidden as expected. Of course, for any other non-modular project every public class in my.donor
module remains visible.
Please see a minimal working example on GitHub.
I am curious whether it is a bug or a conscious design. What's the purpose of this approach?