You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java模块系统:如何避免传递模块的所有包泄露?

Java模块系统限制传递依赖暴露范围的方法

当你使用requires transitive greetings时,greetings模块中所有exports的包都会被传递给依赖hellomodule的模块。若要限制仅特定类/包对外可见,可通过以下核心方式实现:

1. 让依赖模块定向导出特定包给当前模块

修改greetings模块的声明,仅将需要被访问的包定向导出给hellomodule,而非全局导出:

module greetings {
    // 仅允许hellomodule访问指定包
    exports com.name.greetings.api to hellomodule;
    // greetings的其他包仅模块内部可见,不会对外暴露
}

然后在hellomodule中用普通requires替代requires transitive:

module hellomodule {
    exports com.name.hello;
    requires greetings;
}

效果:

  • hellomodule可正常访问greetings的指定包
  • 依赖hellomodule的模块无法直接访问greetings的任何包,除非hellomodule主动导出相关类型

2. 封装依赖模块类型,对外暴露自有API

如果不想让依赖方接触greetings的任何类型,可在hellomodule中封装底层功能,对外暴露自定义的接口或类:

// hellomodule的对外API类
package com.name.hello;
public class HelloService {
    private final com.name.greetings.Greeter greeter = new com.name.greetings.Greeter();
    
    // 对外方法仅使用自有类型或基础类型,不直接返回greetings的类
    public String sayHello(String name) {
        return greeter.greet(name);
    }
}

此时hellomodule的声明只需普通依赖:

module hellomodule {
    exports com.name.hello;
    requires greetings;
}

这种方式下,依赖方完全看不到greetings模块的任何类型,仅能通过hellomodule提供的API交互,彻底隔离底层依赖暴露。

补充:若必须在API中使用依赖模块类型

如果hellomodule的API必须直接返回greetings的类(比如方法签名含com.name.greetings.Greeter),则依赖方必须能访问该类,无法完全隐藏,但可以:

  • 让greetings仅导出包含该类的包,而非所有包
  • 不使用requires transitive,由依赖方自行requires greetings(但依赖方仍能访问greetings导出的包)
  • 或让greetings定向导出该包给hellomodule和指定依赖方,不过此方式需明确指定所有依赖方,灵活性较低

内容的提问来源于stack exchange,提问作者GionJh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:30:38