带 Guice 的 Spigot 在 internal.Messages$FormatOptions 上给出 NoClassDefFoundError
Spigot with Guice gives NoClassDefFoundError on internal.Messages$FormatOptions
我一直在研究 Guice,偶然发现了这个对我来说似乎没有多大意义的错误。似乎每当注入过程中发生错误时,Guice 由于消息格式化失败而无法正确记录注入错误。这可能是 Guice 中的一个错误,我不完全确定。
正在使用 maven-shade-plugin
构建 jar,它在 jar 本身中包含必要的依赖项。查看 jar 的内容,它确实包含 NoClassDefFoundError
所指的 class。注入本身完全可以正常工作,只要它不 运行 进入任何 class 就无法正确注入。
这个奇怪的原因是发生异常的代码与丢失的 class 在完全相同的文件中。以下屏幕截图是使用 IntelliJ 的内置反编译器截取的:
com.google.inject.internal
通过 winrar 的 jar 内容:
堆栈跟踪:
[23:32:10 WARN]: AsyncLogger error handling event seq=231, value='org.apache.logging.log4j.core.async.RingBufferLogEvent@64c2c9e5': java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: com/google/inject/internal/Messages$FormatOptions
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.internal.Messages.redBold(Messages.java:306)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.spi.ErrorDetail.lambda$format[=11=](ErrorDetail.java:61)
[23:32:10 WARN]: at java.base/java.util.Optional.map(Optional.java:260)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.spi.ErrorDetail.format(ErrorDetail.java:61)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.internal.Messages.formatMessages(Messages.java:90)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.ProvisionException.getMessage(ProvisionException.java:60)
[23:32:10 WARN]: at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:106)
[23:32:10 WARN]: at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:94)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrownProxy(RingBufferLogEvent.java:326)
[23:32:10 WARN]: at io.papermc.paper.logging.DelegateLogEvent.getThrownProxy(DelegateLogEvent.java:103)
[23:32:10 WARN]: at io.papermc.paper.logging.ExtraClassInfoLogEvent.getThrownProxy(ExtraClassInfoLogEvent.java:21)
[23:32:10 WARN]: at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:63)
[23:32:10 WARN]: at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout$PatternSelectorSerializer.toSerializable(PatternLayout.java:475)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:244)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:229)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.append(RollingRandomAccessFileAppender.java:251)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.rewrite.RewriteAppender.append(RewriteAppender.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.rewrite.RewriteAppender.append(RewriteAppender.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:540)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:498)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:481)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:469)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:98)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:488)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:154)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:46)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
[23:32:10 WARN]: at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
[23:32:10 WARN]: at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
[23:32:10 WARN]: at java.base/java.lang.Thread.run(Thread.java:831)
Main Pom.xml(注意 Valve 是包含 guice 的):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mpolder</groupId>
<artifactId>Dodgeball</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>Cameo-Dodgeball</finalName>
<relocations>
<relocation>
<pattern>com.mpolder.valve</pattern>
<shadedPattern>com.mpolder.dodgeball.valve</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>maven-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mpolder</groupId>
<artifactId>Valve</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.7-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
阀门pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mpolder</groupId>
<artifactId>Valve</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdbi/jdbi3-core -->
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-core</artifactId>
<version>3.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdbi/jdbi3-core -->
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-sqlobject</artifactId>
<version>3.23.0</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
所以,这可能不是任何人(包括我)所希望的解决方案
事实证明,我使用的名为 spigot(bukkit 的扩展)的库有自己的 classloader 实现。这个 classloader 似乎无法正常运行,并且无法加载 subclass 即使 class 在 class路径.
一旦找到问题的原因,我能想到的唯一方法是使用 Google Guava 手动加载 class。这已经解决了这个问题,尽管是以一种非常肮脏的方式。不过它只需要 运行 一次,所以我把它藏在了一个名为 bukkit 的方法的深处。
如果您想知道我是如何修复它的,请准备好进行一次狂野之旅:
List<String> toLoad = Arrays.asList(
"com.google.inject.internal.Messages$FormatOptions",
"com.google.inject.internal.util.LineNumbers",
"com.google.inject.internal.util.LineNumbers$LineNumberReader",
"com.google.inject.internal.PackageNameCompressor",
"com.google.inject.internal.ErrorFormatter"
);
try {
Set<ClassPath.ClassInfo> cp = ClassPath.from(ValvePlugin.class.getClassLoader()).getAllClasses();
for (ClassPath.ClassInfo x : cp) {
if (toLoad.contains(x.getName())) {
x.load();
}
}
} catch (IOException e) {
e.printStackTrace();
}
此代码手动扫描整个class路径中的所有classes(我不能'找不到一种仅扫描一个包同时还包括子classes) 并加载列表中存在的任何名称的快速方法。
我一直在研究 Guice,偶然发现了这个对我来说似乎没有多大意义的错误。似乎每当注入过程中发生错误时,Guice 由于消息格式化失败而无法正确记录注入错误。这可能是 Guice 中的一个错误,我不完全确定。
正在使用 maven-shade-plugin
构建 jar,它在 jar 本身中包含必要的依赖项。查看 jar 的内容,它确实包含 NoClassDefFoundError
所指的 class。注入本身完全可以正常工作,只要它不 运行 进入任何 class 就无法正确注入。
这个奇怪的原因是发生异常的代码与丢失的 class 在完全相同的文件中。以下屏幕截图是使用 IntelliJ 的内置反编译器截取的:
com.google.inject.internal
通过 winrar 的 jar 内容:
堆栈跟踪:
[23:32:10 WARN]: AsyncLogger error handling event seq=231, value='org.apache.logging.log4j.core.async.RingBufferLogEvent@64c2c9e5': java.lang.NoClassDefFoundError: java.lang.NoClassDefFoundError: com/google/inject/internal/Messages$FormatOptions
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.internal.Messages.redBold(Messages.java:306)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.spi.ErrorDetail.lambda$format[=11=](ErrorDetail.java:61)
[23:32:10 WARN]: at java.base/java.util.Optional.map(Optional.java:260)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.spi.ErrorDetail.format(ErrorDetail.java:61)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.internal.Messages.formatMessages(Messages.java:90)
[23:32:10 WARN]: at Dodgeball.jar//com.google.inject.ProvisionException.getMessage(ProvisionException.java:60)
[23:32:10 WARN]: at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:106)
[23:32:10 WARN]: at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:94)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrownProxy(RingBufferLogEvent.java:326)
[23:32:10 WARN]: at io.papermc.paper.logging.DelegateLogEvent.getThrownProxy(DelegateLogEvent.java:103)
[23:32:10 WARN]: at io.papermc.paper.logging.ExtraClassInfoLogEvent.getThrownProxy(ExtraClassInfoLogEvent.java:21)
[23:32:10 WARN]: at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:63)
[23:32:10 WARN]: at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout$PatternSelectorSerializer.toSerializable(PatternLayout.java:475)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:244)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:229)
[23:32:10 WARN]: at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.append(RollingRandomAccessFileAppender.java:251)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.rewrite.RewriteAppender.append(RewriteAppender.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.appender.rewrite.RewriteAppender.append(RewriteAppender.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:540)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:498)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:481)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:469)
[23:32:10 WARN]: at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:98)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:488)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:154)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:46)
[23:32:10 WARN]: at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
[23:32:10 WARN]: at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
[23:32:10 WARN]: at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
[23:32:10 WARN]: at java.base/java.lang.Thread.run(Thread.java:831)
Main Pom.xml(注意 Valve 是包含 guice 的):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mpolder</groupId>
<artifactId>Dodgeball</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>Cameo-Dodgeball</finalName>
<relocations>
<relocation>
<pattern>com.mpolder.valve</pattern>
<shadedPattern>com.mpolder.dodgeball.valve</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>maven-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</pluginRepository>
</pluginRepositories>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.mpolder</groupId>
<artifactId>Valve</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.7-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
阀门pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mpolder</groupId>
<artifactId>Valve</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>22.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdbi/jdbi3-core -->
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-core</artifactId>
<version>3.23.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.jdbi/jdbi3-core -->
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-sqlobject</artifactId>
<version>3.23.0</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.16.5-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
所以,这可能不是任何人(包括我)所希望的解决方案
事实证明,我使用的名为 spigot(bukkit 的扩展)的库有自己的 classloader 实现。这个 classloader 似乎无法正常运行,并且无法加载 subclass 即使 class 在 class路径.
一旦找到问题的原因,我能想到的唯一方法是使用 Google Guava 手动加载 class。这已经解决了这个问题,尽管是以一种非常肮脏的方式。不过它只需要 运行 一次,所以我把它藏在了一个名为 bukkit 的方法的深处。
如果您想知道我是如何修复它的,请准备好进行一次狂野之旅:
List<String> toLoad = Arrays.asList(
"com.google.inject.internal.Messages$FormatOptions",
"com.google.inject.internal.util.LineNumbers",
"com.google.inject.internal.util.LineNumbers$LineNumberReader",
"com.google.inject.internal.PackageNameCompressor",
"com.google.inject.internal.ErrorFormatter"
);
try {
Set<ClassPath.ClassInfo> cp = ClassPath.from(ValvePlugin.class.getClassLoader()).getAllClasses();
for (ClassPath.ClassInfo x : cp) {
if (toLoad.contains(x.getName())) {
x.load();
}
}
} catch (IOException e) {
e.printStackTrace();
}
此代码手动扫描整个class路径中的所有classes(我不能'找不到一种仅扫描一个包同时还包括子classes) 并加载列表中存在的任何名称的快速方法。