Gradle构建报错:build/src-gen下类找不到javax.persistence包
Gradle项目生成JPA实体类编译报错排查方案
问题现象
- 构建多模块Gradle项目时,Hibernate从XML生成到
build/src-gen目录下的实体类编译失败,报错:/tobris-erp/build/src-gen/java/com/tobris/dms/db/DMSFile.java:9: error: package javax.persistence does not exist - Eclipse环境下无该报错,已确认
javax.persistence-api相关Jar包实际存在 - 项目结构如下:
|── build | |──src-gen | ├── buildSrc │ ├─gradle.build (2) | ├── modules │ ├── tobris-open-suite │ ├── tobris-accounting │ | └── gralde.build ├ ├──tobris-admin | └── gralde.build | ├── tobris-erp └── gralde.build (1)
核心原因
依赖配置的作用域完全搞错了:
- 根build.gradle里
buildscript块下声明的classpath依赖,只给Gradle构建流程本身使用——比如自定义Gradle任务、第三方Gradle插件可以读取这些依赖,项目业务代码、自动生成的代码编译时完全无法访问这个作用域的Jar包 buildSrc目录下声明的依赖同理,仅对写在buildSrc里的自定义构建逻辑生效,不会传递到主项目的编译类路径- 额外问题:没有将
build/src-gen目录注册为Gradle识别的源码目录,默认编译任务不会扫描该路径下的代码。Eclipse会自动关联build目录下的生成源码、匹配全量依赖,因此不会触发该报错。
排查步骤
- 在项目根目录执行命令
./gradlew dependencies --configuration compileClasspath(Windows环境替换为gradlew.bat dependencies --configuration compileClasspath),查看输出的依赖树中是否存在javax.persistence:javax.persistence-api:2.2,不存在则说明依赖确实未加入编译类路径 - 执行命令
./gradlew properties | grep sourceSets,查看main源码集包含的目录列表中是否存在build/src-gen/java,不存在则生成的代码不会被纳入编译流程 - 检查任务执行顺序,确认Hibernate生成实体类的任务在
compileJava任务之前运行,避免编译时代码还未生成
修复方案
按以下两步修改配置即可解决:
- 将业务编译需要的JPA、Hibernate依赖从
buildscript块迁移到正常的项目依赖作用域。如果所有子模块都需要使用这类依赖,就放在根build.gradle的allprojects块中;如果仅tobris-erp模块使用,直接加在tobris-erp模块的dependencies块中即可:
dependencies { implementation "org.hibernate:hibernate-core:5.6.5.Final" implementation "org.hibernate:hibernate-hikaricp:5.6.5.Final" implementation "org.hibernate:hibernate-validator:5.4.1.Final" implementation "org.hibernate:hibernate-jcache:5.6.5.Final" implementation 'javax.persistence:javax.persistence-api:2.2' }
额外说明:原配置在buildscript的dependencies中重复声明了两次
javax.persistence:javax.persistence-api:2.2,该配置对业务代码编译无效,可以直接删除。
- 注册生成代码目录为正式源码目录,同时绑定任务执行顺序,保证代码生成在编译前完成,在生成代码所在模块的build.gradle中添加如下配置:
sourceSets { main { java { srcDir "${buildDir}/src-gen/java" } } } // 将generateHibernateEntities替换为你实际用于从XML生成实体类的Gradle任务名 compileJava.dependsOn generateHibernateEntities
配置修改完成后,执行./gradlew clean build即可正常完成编译。
内容的提问来源于stack exchange,提问作者Maher Ben Taleb Ali
相关产品推荐
相关产品推荐

