Spigot插件配置EBean时出现SpiRawSqlService未找到问题
PaperMC插件中Ebean QueryBean无法找到SpiRawSqlService实现的解决方案
问题描述
为PaperMC插件配置Ebean ORM时,已成功将Ebean依赖打包进插件,普通数据保存、非QueryBean查询功能正常,但使用QueryBean创建查询时,初始化相关类会抛出以下错误:
Caused by: java.lang.IllegalStateException: No service implementation found for interface org.example.ebean.io.ebean.service.SpiRawSqlService
环境信息
- PaperMC版本:paper-1.19.3-367.jar
- Java版本:18
- 开发工具:IntelliJ Ebean增强插件(已确认启用)
- Gradle插件版本:io.ebean 13.10.0、shadowJar 7.1.2
核心问题分析
- 反编译打包后的shadowJar发现,
SpiRawSqlService的实现类DRawSql位于org.example.ebean.io.ebeaninternal.server.rawsql包下,但通过ClassLoader#getDefinedPackages查看,org.example.ebean.io.ebeaninternal包及其子包并未被类加载器识别加载。 - Ebean内部服务通过SPI机制加载实现类,若内部包未被正确加载,SPI无法找到对应的实现类,从而抛出错误。
解决方案
1. 完善ShadowJar的包重定位配置
确保shadowJar的重定位规则同时覆盖io.ebean和io.ebeaninternal包,避免遗漏内部包。在build.gradle中修改shadowJar配置:
shadowJar { // 重定位Ebean核心包 relocate 'io.ebean', 'org.example.ebean.io.ebean' // 重定位Ebean内部实现包 relocate 'io.ebeaninternal', 'org.example.ebean.io.ebeaninternal' }
2. 调整Ebean增强插件的包范围
确保Ebean Gradle插件的增强规则包含Ebean内部包,避免内部类未被正确增强。在build.gradle的ebean配置中补充:
ebean { enhancement { // 包含你的实体类包、Ebean核心包及内部实现包 packages = ["org.example.database.**", "io.ebean.**", "io.ebeaninternal.**"] } }
3. 验证SPI配置文件的正确性
Ebean通过META-INF/services下的配置文件实现SPI加载,需确保这些文件的内容已被正确重定位:
- 找到重定位后的
META-INF/services/org.example.ebean.io.ebean.service.SpiRawSqlService文件 - 确认文件内的内容为
org.example.ebean.io.ebeaninternal.server.rawsql.DRawSql,即重定位后的实现类全类名 - 若shadowJar未自动修改这些文件,可手动配置shadowJar的
transform规则来替换文件内容。
4. 手动验证类加载情况
在插件初始化代码中添加类加载验证,确认DRawSql类可被加载:
@Override public void onEnable() { try { Class.forName("org.example.ebean.io.ebeaninternal.server.rawsql.DRawSql"); getLogger().info("DRawSql类加载成功"); } catch (ClassNotFoundException e) { getLogger().severe("无法加载DRawSql类:" + e.getMessage()); e.printStackTrace(); } }
内容的提问来源于stack exchange,提问作者Apple Ptr
相关产品推荐
相关产品推荐

