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

Maven迁移Bazel异常:全局BUILD引用子模块时注解生成类找不到

解决Bazel迁移中注解处理器生成类跨模块找不到的问题

我之前把Maven项目迁移到Bazel时,也碰到过一模一样的问题!单独编译子模块一切正常,但全局编译父模块时,死活找不到注解处理器生成的QSmsGatewaySettings类,折腾了好一阵才找到根源。

问题核心

Bazel默认会做未使用代码剔除优化:如果你的子模块appdirect_sms_gateway_settings_impl自身代码没有引用QSmsGatewaySettings(只有父模块需要它),Bazel会判定这个类是无用的,不会把它打包到子模块的输出jar里。而Maven没有这种优化逻辑,所以之前在Maven环境下不会出现这个问题。

另外,你通过依赖mysema_query(带exported_plugins)来应用注解处理器,生成的类属于appdirect_sms_gateway_settings_impl,但因为没有被子模块自身引用,就被Bazel过滤掉了。

可行解决方案

这里按推荐程度给你三个方案:

1. 强制保留未被引用的生成类(最简单)

在子模块的appdirect_sms_gateway_settings_impl配置中添加javacopts,告诉javac保留所有符号,避免Bazel剔除未被引用的生成类:

java_library(
    name = "appdirect_sms_gateway_settings_impl",
    srcs = glob(["src/main/java/**/*.java"]),
    javacopts = ["-XDkeepUnusedSymbols"], # 关键配置
    deps = [ ":mysema_query", … ],
)

这个选项会让javac保留所有生成的类,不管是否被当前模块引用,父模块依赖子模块时就能正常找到QSmsGatewaySettings了。

2. 在子模块中添加“标记类”引用生成类

如果不想修改编译选项,可以在子模块中写一个空的“标记类”,显式引用QSmsGatewaySettings,让Bazel认为这个类是有用的:

// 放在子模块src/main/java下任意包路径即可
public class QuerydslMarker {
    // 仅用于标记引用,无需实际调用
    private static final Class<?> MARKER = QSmsGatewaySettings.class;
}

这样Bazel就会把QSmsGatewaySettings打包到子模块的输出jar里。

3. 拆分生成类到独立模块(最规范)

如果项目规模较大,推荐把注解处理器生成的Querydsl类单独拆成一个java_library,让子模块和父模块都依赖这个独立模块:

# 子模块BUILD文件中新增独立的Querydsl模块
java_library(
    name = "sms_gateway_querydsl",
    srcs = glob(["src/main/java/**/*.java"]), # 这里放你的JPA实体类
    plugins = [":mysema_query_plugin"],
    deps = [":mysema_query"],
)

# 修改原有的业务模块配置
java_library(
    name = "appdirect_sms_gateway_settings_impl",
    srcs = glob(["src/main/java/**/*.java"]),
    deps = [":sms_gateway_querydsl", …],
)

然后在父模块中同时依赖业务模块和Querydsl模块:

java_library(
    name = "appdirect-parent",
    srcs = glob(["*.java"]),
    deps = [
        …,
        "appdirect-sms-gateway/appdirect-sms-gateway-settings-impl:appdirect_sms_gateway_settings_impl",
        "appdirect-sms-gateway/appdirect-sms-gateway-settings-impl:sms_gateway_querydsl"
    ],
)

这种方式结构更清晰,从根源上避免了代码剔除的问题。

验证方法

你可以先单独编译子模块,然后检查输出jar里是否包含目标类:

jar tf bazel-bin/appdirect-sms-gateway/appdirect-sms-gateway-settings-impl/libappdirect_sms_gateway_settings_impl.jar | grep QSmsGatewaySettings

如果执行解决方案后能看到这个类,说明配置生效,再运行全局编译就没问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:05:17