java - 对于其他非模块化项目,如何使 Java 类在其模块之外不可见?
问题描述
最近我发现,如果模块内的包包含公共接口或类,它们会自动导出,因此在接收者代码未模块化时无意中在模块外部可见。
项目结构如下
parent
sub-donor (java-module)
my/project/first
Cowboy.java
module-info.java
sub-recipient (has no module-info)
my/project/somewhere
Main.java
模块信息.java
module my.donor {
// nothing is exported here
}
牛仔.java
public class Cowboy {
public String say() { return "eee-ha"; }
}
主.java
import my.project.first.Cowboy;
public class Main {
public static void main(String[] args) {
Cowboy g = new Cowboy();
System.out.println(g.say());
}
}
包中的类my.project.first
应该my.donor
只在模块中使用,并且在模块之外是不可见的。
没想到它在模块外可见,好像有一行,所以可以编译exports my.project.first;
该类。Main
限制可见性的方法是制作sub-recipient
一个 java 模块,添加module-info.java
,然后其中的所有内容都sub-donor
按预期隐藏。当然,对于任何其他非模块化项目,my.donor
模块中的每个公共类都是可见的。
请在 GitHub 上查看一个最小的工作示例。
我很好奇这是一个错误还是一个有意识的设计。这种方法的目的是什么?
解决方案
TL;DR — Maven 的问题。直接编译javac
按预期工作。
长篇大论的版本
„<em>...完整命令只是在父项目上 mvn 编译...</em>“</p>
这就是你的问题。Maven 有一个令人惊讶的特性,它只会将子项目视为 JPMS 模块IFF 所有子项目都有模块描述符。
所以因为只有你的sub-donor
Maven 模块有 JPMS 模块描述符,所以你的两个子项目都在类路径上编译……</p>
$ mvn -e -X compile
…
[INFO] Changes detected - recompiling the module!
[DEBUG] Classpath:
[DEBUG] sample-so-question-61888059-dev/sub-recipient/target/classes
[DEBUG] sample-so-question-61888059-dev/sub-donor/target/classes
…
[DEBUG] Command line options:
[DEBUG] -d sample-so-question-61888059-dev/sub-recipient/target/classes -classpath sample-so-question-61888059-dev/sub-recipient/target/classes;sample-so-question-61888059-dev/sub-donor/target/classes;…
…
并且因为两者都在类路径上,所以sub-donor
子项目的模块描述符被渲染为无效。
如果您自己动手并javac
直接运行(假设您已经sub-donor
预先编译了项目)......</p>
javac --add-modules my.donor --module-path sample-so-question-61888059-dev/sub-donor/target/classes --class-path sample-so-question-61888059-dev/sub-recipient/target/classes -d sample-so-question-61888059-dev/sub-recipient/target/classes sample-so-question-61888059-dev/sub-recipient/src/main/java/my/somewhere/*.java
那么javac
确实会像有意识地设计那样犹豫不决……</p>
sample-so-question-61888059-dev/sub-recipient/src/main/java/my/somewhere/Main.java:3: error: package my.project.first is not visible
import my.project.first.Cowboy;
^
(package my.project.first is declared in module my.donor, which does not export it)
1 error
推荐阅读
- java - Java 应用程序的配置文件
- node.js - jest 和 npm 没有运行测试,只是挂起
- php - PHP 语法,是 $this->(stuff) ->(more stuff) 和 $this->(stuff); 一样 $this->(更多东西)?
- javascript - 不要使用 React-Select 清除选择时的输入
- java - spring cache - 如果更新逻辑失败,如何恢复到原始缓存?- @cacheable @cacheput @cacheevict
- javascript - javascript中通用模板文字函数的标记
- python - 如何从django中的子对象获取父对象
- javascript - 打字稿这个表达式是不可构造的。继承类结构错误
- c# - C# EnterpriseLibrary 获取输出参数时遇到问题
- c# - 安卓模拟器上的状态栏颜色没有变化吗?