У меня проблемы с использованием вспомогательной инъекции Guice в моем плагине spigot, и я не могу решить эту проблему. Это ошибка, которую я получаю:
> [12:00:38 INFO]: [DestinyMC] Enabling DestinyMC v1.0
> 2019-01-14 12:00:41,492 Log4j2-TF-1-AsyncLogger[AsyncContext@5c647e05]-1 ERROR An exception occurred processing Appender File com.google.common.util.concurrent.UncheckedExecutionException: java.lang.IllegalStateException: zip file closed
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2217)
at com.google.common.cache.LocalCache.get(LocalCache.java:4154)
at com.google.common.cache.LocalCache.getOrLoad(LocalCache.java:4158)
at com.google.common.cache.LocalCache$LocalLoadingCache.get(LocalCache.java:5147)
at com.google.common.cache.LocalCache$LocalLoadingCache.getUnchecked(LocalCache.java:5153)
at com.google.inject.internal.util.StackTraceElements.forMember(StackTraceElements.java:71)
at com.google.inject.internal.Messages.formatSource(Messages.java:241)
at com.google.inject.internal.Messages.formatSource(Messages.java:220)
at com.google.inject.internal.Messages.formatMessages(Messages.java:90)
at com.google.inject.CreationException.getMessage(CreationException.java:50)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:134)
at org.apache.logging.log4j.core.impl.ThrowableProxy.<init>(ThrowableProxy.java:122)
at org.apache.logging.log4j.core.async.RingBufferLogEvent.getThrownProxy(RingBufferLogEvent.java:330)
at org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.format(ExtendedThrowablePatternConverter.java:61)
at org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
at org.apache.logging.log4j.core.layout.PatternLayout$PatternSelectorSerializer.toSerializable(PatternLayout.java:455)
at org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:232)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:217)
at org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:57)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:177)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:170)
at org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:161)
at org.apache.logging.log4j.core.appender.RollingRandomAccessFileAppender.append(RollingRandomAccessFileAppender.java:218)
at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:448)
at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:433)
at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:417)
at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:79)
at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:337)
at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:161)
at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:45)
at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: zip file closed
at java.util.zip.ZipFile.ensureOpen(Unknown Source)
at java.util.zip.ZipFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getEntry(Unknown Source)
at java.util.jar.JarFile.getJarEntry(Unknown Source)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:120)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:104)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at com.google.inject.internal.util.StackTraceElements$1.load(StackTraceElements.java:49)
at com.google.inject.internal.util.StackTraceElements$1.load(StackTraceElements.java:45)
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3716)
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2424)
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2298)
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2211)
... 39 more
Это мой класс Binder:
public class MainBinder extends AbstractModule {
@Override
protected void configure() {
bind(DestinyMC.class).toInstance(this.plugin);
install(new FactoryModuleBuilder().build(InventoryFromFileFactory.class));
}
Ошибка исчезает, когда я закомментирую строку установки. Эта строка использует этот фабричный класс
public interface InventoryFromFileFactory {
InventoryFromFile create(String targetRootKey, String targetFile);
}
, который объявляет параметры, которые должны быть предоставлены вручную при создании объекта для этого класса:
public class InventoryFromFile {
@Inject
public InventoryFromFile
(
@Assisted String targetRootKey,
@Assisted String targetFile,
ConfigAccessorFactory configAccessorFactory
)
{
ConfigurationSection targetCS = configAccessorFactory.create(targetFile).getCustomConfig().getConfigurationSection(targetRootKey);
...
}
}
ConfigAccessFactory
- это еще один фабричный класс для вспомогательной инъекции
public interface ConfigAccessorFactory {
ConfigAccessor create(String filename);
}
, который используется здесь:
public class ConfigAccessor {
private Plugin plugin;
private final String customFileName;
@Inject
public ConfigAccessor
(
@Assisted String fileName,
DestinyMC plugin
)
{
this.customFileName = fileName;
this.plugin = plugin;
}
...
}
Наконец, зависимость DestinyMC
является основным классом для плагина spigot:
public class DestinyMC extends JavaPlugin {
//Inject dependencies
@Inject private ConfigAccessorFactory configAccessorFactory;
//Code only run once when the plugin is enabled
public void onEnable() {
MainBinder mainBinder = new MainBinder(this);
Injector injector = Guice.createInjector(mainBinder);
injector.injectMembers(this);
//Saves config files to disk if they don't exist
saveDefaultConfig();
Arrays.asList(
"inventory-gui.yml",
"player-tree-template.yml",
"player-tree-data.yml"
).forEach((file) -> {
configAccessorFactory.create(file).saveDefaultConfig();
});
...
}
Я не слишком уверен, что я делаю неправильно, но я довольно новичок в Guice, поэтому я, скорее всего, что-то неправильно понимаю. Кроме того, если есть просто лучший способ сделать это, дайте мне знать. Спасибо за помощь.