MilkBowl / VaultAPI

API Component of Vault
GNU Lesser General Public License v3.0
273 stars 109 forks source link

java.lang.IllegalStateException: zip file closed #162

Open samldm opened 11 months ago

samldm commented 11 months ago

Hello there, i have an error while trying to get the chat provider

spigot version: 1.20.1

plugins:

there is the error:

[13:52:05] [Server thread/ERROR]: Error occurred while enabling ServerCore v1.0.0 (Is it up to date?)
java.lang.IllegalStateException: zip file closed
        at java.util.zip.ZipFile.ensureOpen(ZipFile.java:831) ~[?:?]
        at java.util.zip.ZipFile.getEntry(ZipFile.java:330) ~[?:?]
        at java.util.jar.JarFile.getEntry(JarFile.java:518) ~[?:?]
        at java.util.jar.JarFile.getJarEntry(JarFile.java:473) ~[?:?]
        at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:159) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:587) ~[?:?]
        at org.bukkit.plugin.java.PluginClassLoader.loadClass0(PluginClassLoader.java:104) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.java.PluginClassLoader.loadClass(PluginClassLoader.java:99) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[?:?]
        at fr.samldm.servercore.hooks.VaultHook.setupChat(VaultHook.java:37) ~[?:?]
        at fr.samldm.servercore.hooks.VaultHook.setup(VaultHook.java:53) ~[?:?]
        at fr.samldm.servercore.ServerCore.onEnable(ServerCore.java:29) ~[?:?]
        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:266) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:342) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:480) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugin(CraftServer.java:546) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at org.bukkit.craftbukkit.v1_20_R1.CraftServer.enablePlugins(CraftServer.java:460) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at net.minecraft.server.MinecraftServer.loadWorld0(MinecraftServer.java:588) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at net.minecraft.server.MinecraftServer.loadLevel(MinecraftServer.java:413) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at net.minecraft.server.dedicated.DedicatedServer.e(DedicatedServer.java:250) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:972) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at net.minecraft.server.MinecraftServer.lambda$0(MinecraftServer.java:303) ~[spigot-1.20.1-R0.1-SNAPSHOT.jar:3871-Spigot-d2eba2c-3f9263b]
        at java.lang.Thread.run(Thread.java:833) ~[?:?]

There is my code:

JavaPlugin:


public final class ServerCore extends JavaPlugin {

    private static ServerCore instance;

    public static ServerCore getInstance() {
        return instance;
    }

    @Override
    public void onEnable() {
        instance = this;

        if (getServer().getPluginManager().getPlugin("Vault") == null) {
            System.out.println("[Core] Missing Vault!");
            getServer().getPluginManager().disablePlugin(this);
            return;
        }
        VaultHook.getInstance().setup();

        // ...

        getLogger().info(" @ ServerCore enabled");
    }
}

VaultHook class:

public class VaultHook {

    private static VaultHook instance = new VaultHook();

    private static Economy econ = null;
    private static Permission perms = null;
    private static Chat chat = null;

    public static VaultHook getInstance() {
        return instance;
    }

    private VaultHook() {
    }

    private boolean setupEconomy() {
        if (ServerCore.getInstance().getServer().getPluginManager().getPlugin("Vault") == null) {
            return false;
        }
        RegisteredServiceProvider<Economy> rsp = ServerCore.getInstance().getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp == null) {
            return false;
        }
        econ = rsp.getProvider();
        return econ != null;
    }

    private boolean setupChat() {
        RegisteredServiceProvider<Chat> rsp = ServerCore.getInstance().getServer().getServicesManager().getRegistration(Chat.class);
        chat = rsp.getProvider();
        return chat != null;
    }

    private boolean setupPermissions() {
        RegisteredServiceProvider<Permission> rsp = ServerCore.getInstance().getServer().getServicesManager().getRegistration(Permission.class);
        perms = rsp.getProvider();
        return perms != null;
    }

    public void setup() {
        if (!setupEconomy()) {
            ServerCore.getInstance().getLogger().severe("Vault not found!");
            ServerCore.getInstance().getServer().getPluginManager().disablePlugin(ServerCore.getInstance());
        }
        setupChat();
        setupPermissions();
    }

    public Economy getEconomy() {
        return econ;
    }

    public Permission getPermissions() {
        return perms;
    }

    public Chat getChat() {
        return chat;
    }
}
Geolykt commented 11 months ago

ALWAYS get the service provider lazily - that is as late as possible, but preferably via https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/server/ServiceRegisterEvent.html.

If it is done eagerly you risk that the economy plugin hasn't been initialized yet which would necessarily blow up your plugin.

However this approach doesn't guard against the event where there is no economy plugin - at which point you just have to roll the dice and decide what you do from there (either do nothing and crash with a NPE, disable plugin when no eco plugin is active or disable certain functionalities of your plugin if the eco plugin is absent)


The most basic solution is to register stuff on the 1st tick. BUT NEVER EVER OBTAIN THE SERVICE PROVIDER IN YOUR ONENABLE() OR CONSTURCTOR


Make sure you have Vault declared as a dependency in your plugin.yml The above stacktrace is likely induced by ServerCore.getInstance().getServer().getPluginManager().disablePlugin(ServerCore.getInstance()); and further things in your code attempting to load additional classes. However once you invoke disablePlugin, the classloader is closed and you MUST NOT (as per RFC 2119) load any classes - be it classes of your plugin or classes of other plugins (in your case Vault's Chat interface). A disabled plugin ought normally perform no actions.