Bukkit插件加载失败求助:导入mirai-core后启动报错
问题:导入mirai-core后Bukkit插件加载失败
导入mirai-core依赖前,Bukkit插件运行完全正常,但导入该依赖并调用其API后,服务器启动阶段就出现插件加载失败的错误,已排除QQ登录失败的可能性。
服务器错误日志
Starting org.bukkit.craftbukkit.Main *** Warning, you've not updated in a while! *** *** Please download a new build as per instructions from https://papermc.io/downloads/paper *** System Info: Java 19 (OpenJDK 64-Bit Server VM 19.0.1+10-21) Host: Windows 11 10.0 (amd64) Loading libraries, please wait... 2023-07-04 09:39:37,444 ServerMain WARN Advanced terminal features are not available in this environment [09:39:40 ERROR]: [DirectoryProviderSource] Error loading plugin: Directory 'plugins\QToSer-1.0-SNAPSHOT.jar' failed to load! java.lang.RuntimeException: Directory 'plugins\QToSer-1.0-SNAPSHOT.jar' failed to load! at io.papermc.paper.plugin.provider.source.FileProviderSource.registerProviders(FileProviderSource.java:59) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.source.DirectoryProviderSource.lambda$registerProviders$1(DirectoryProviderSource.java:34) ~[paper-1.20.jar:git-Paper-3] at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183) ~[?:?] at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[?:?] at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[?:?] at java.util.Iterator.forEachRemaining(Iterator.java:133) ~[?:?] at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1921) ~[?:?] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?] at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:?] at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:?] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?] at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[?:?] at io.papermc.paper.plugin.provider.source.DirectoryProviderSource.registerProviders(DirectoryProviderSource.java:32) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.source.DirectoryProviderSource.registerProviders(DirectoryProviderSource.java:14) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.util.EntrypointUtil.registerProvidersFromSource(EntrypointUtil.java:14) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.PluginInitializerManager.load(PluginInitializerManager.java:100) ~[paper-1.20.jar:git-Paper-3] at net.minecraft.server.Main.main(Main.java:126) ~[paper-1.20.jar:git-Paper-3] at org.bukkit.craftbukkit.Main.main(Main.java:316) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paperclip.Paperclip.lambda$main$0(Paperclip.java:42) ~[app:?] at java.lang.Thread.run(Thread.java:1589) ~[?:?] Caused by: java.lang.SecurityException: Invalid signature file digest for Manifest main attributes at sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:340) ~[?:?] at sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:282) ~[?:?] at java.util.jar.JarVerifier.processEntry(JarVerifier.java:327) ~[?:?] at java.util.jar.JarVerifier.update(JarVerifier.java:239) ~[?:?] at java.util.jar.JarFile.initializeVerifier(JarFile.java:760) ~[?:?] at java.util.jar.JarFile.getInputStream(JarFile.java:846) ~[?:?] at io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProviderFactory.create(SpigotPluginProviderFactory.java:36) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.type.spigot.SpigotPluginProviderFactory.create(SpigotPluginProviderFactory.java:16) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.type.PluginFileType.getConfig(PluginFileType.java:77) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.type.PluginFileType.register(PluginFileType.java:70) ~[paper-1.20.jar:git-Paper-3] at io.papermc.paper.plugin.provider.source.FileProviderSource.registerProviders(FileProviderSource.java:57) ~[paper-1.20.jar:git-Paper-3] ... 20 more [09:39:49 INFO]: Environment: authHost='https://authserver.mojang.com', accountsHost='https://api.mojang.com', sessionHost='https://sessionserver.mojang.com', servicesHost='https://api.minecraftservices.com', name='PROD' [09:39:52 INFO]: Loaded 7 recipes [09:39:53 INFO]: Starting minecraft server version 1.20 [09:39:53 INFO]: Loading properties [09:39:53 INFO]: This server is running Paper version git-Paper-3 (MC: 1.20) (Implementing API version 1.20-R0.1-SNAPSHOT) (Git: dc30ee5) [09:39:53 INFO]: Using 4 threads for Netty based IO
插件相关代码
核心插件类代码
public final class QToSer extends JavaPlugin implements Listener, CommandExecutor { public static void say(String s) { CommandSender sender = Bukkit.getConsoleSender(); sender.sendMessage(s); } public static ToQ toQ = new ToQ(); @Override public void onEnable() { getServer().getPluginManager().registerEvents(new CServerLoad(), this); getServer().getPluginManager().registerEvents(new CAsyncPlayerChat(), this); getServer().getPluginManager().registerEvents(new CPlayerJoinEvent(), this); Bukkit.getPluginCommand("send").setExecutor(this); } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (command.getName().equalsIgnoreCase("send")) { if (!(sender.isOp() || sender.hasPermission("group.vip") || sender.hasPermission("group.lv8"))){ sender.sendMessage("你没有权限让机器人自愿发话"); return true; } try { toQ.bot.getGroup(*********).sendMessage(args[0]); } catch (Exception e) { say(e.getMessage()); return false; } } else if (command.getName().equalsIgnoreCase("loginbot")) { if (sender.isOp()){ toQ.bot.login(); toQ.bot.getEventChannel().registerListenerHost(new ConMessage()); } } return false; } @Override public void onDisable() { } }
ToQ类代码
package org.poem.qtoser; import net.mamoe.mirai.*; import net.mamoe.mirai.utils.BotConfiguration; public class ToQ { public Bot bot; public ToQ(){ bot = BotFactory.INSTANCE.newBot(**********,"**********",new BotConfiguration() {{ setProtocol(MiraiProtocol.ANDROID_PHONE); fileBasedDeviceInfo(); }}); } }
plugin.yml配置
name: QToSer version: '${project.version}' main: org.poem.qtoser.QToSer api-version: 1.19 commands: send: description: 向机器人发送消息. usage: /send [message]
解决方案
错误的核心原因是插件Jar包中包含了mirai依赖自带的签名文件(如.SF、.DSA、.RSA),导致Paper服务器在验证Jar包完整性时触发SecurityException。解决方法是在打包插件时,排除这些签名文件。
Maven配置(使用maven-shade-plugin)
在pom.xml的build/plugins中添加或修改maven-shade-plugin的配置,添加签名文件过滤规则:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <filters> <filter> <artifact>*:*</artifact> <excludes> <exclude>META-INF/*.SF</exclude> <exclude>META-INF/*.DSA</exclude> <exclude>META-INF/*.RSA</exclude> </excludes> </filter> </filters> </configuration> </execution> </executions> </plugin>
Gradle配置(使用shadow插件)
在build.gradle中添加shadowJar的过滤配置:
plugins { id 'java' id 'com.github.johnrengelman.shadow' version '7.1.2' } shadowJar { exclude 'META-INF/*.SF' exclude 'META-INF/*.DSA' exclude 'META-INF/*.RSA' }
重新打包插件后,将新生成的Jar包放入服务器plugins目录,即可正常加载。
内容的提问来源于stack exchange,提问作者BUCYUM
相关产品推荐
相关产品推荐

