Guice Assisted Inject - java.lang.IllegalStateException: zip file closed

1.5k Views Asked by At

I'm having problems with using Guice's assisted inject within my spigot plugin, and can't seem to narrow down the problem. This is the error I'm getting:

> [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

This is my Binder Class:

public class MainBinder extends AbstractModule {

@Override
protected void configure() {
    bind(DestinyMC.class).toInstance(this.plugin);

    install(new FactoryModuleBuilder().build(InventoryFromFileFactory.class));
}

The error goes away when I comment out the install line. That line uses this factory class

public interface InventoryFromFileFactory {
    InventoryFromFile create(String targetRootKey, String targetFile);
}

which declare the parameters that need to be manually provided at object creation for this class:

public class InventoryFromFile {
    @Inject
    public InventoryFromFile
    (
        @Assisted String targetRootKey,
        @Assisted String targetFile,
        ConfigAccessorFactory configAccessorFactory
    )
    {
        ConfigurationSection targetCS = configAccessorFactory.create(targetFile).getCustomConfig().getConfigurationSection(targetRootKey);
    ...
    }
}

The ConfigAccessFactory is another factory class for assisted inject

public interface ConfigAccessorFactory {
    ConfigAccessor create(String filename);
}

which is used here:

public class ConfigAccessor {
    private Plugin plugin;
    private final String customFileName;

    @Inject
    public ConfigAccessor
    (
        @Assisted String fileName,
        DestinyMC plugin
    )
    {
        this.customFileName = fileName;
        this.plugin = plugin;
    }
    ...
}

Finally, the DestinyMC dependency is the main class for the spigot plugin:

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();
    });
    ...
}

I'm not too sure what I'm doing wrong, but I'm fairly new to Guice so I'm most likely misunderstanding something. Also, if there's simply a better way to do this, let me know. Thanks for the help.

0

There are 0 best solutions below