SQLite database connection closed or null Java

46 Views Asked by At

I am trying to make a Ban command for minecraft spigot 1.20.2. I am using SQLITE to store the data. I am using OnPlayerJoinEvent to check to see if the player is banned or not, if they are then we get the baninfo and stop them from entering the server. But when it attempts to get the ban info it errors out at the database connection is closed or null.

Here is the join event code.

    Main plugin = Main.getInstance();

    public JoinEvent(Main plugin)
    {
        this.plugin = plugin;
    }

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent event)
    {
        Player player = event.getPlayer();
        String playerName = event.getPlayer().getName();
        if (isPlayerBanned(playerName)) {
            System.out.println("Person banned.");
            // Get ban information
            BanInfo banInfo = getBanInfo(playerName);

            // Prevent the player from joining
            event.setJoinMessage(null); // Remove default join message
            player.kickPlayer(getKickMessage(banInfo));
        }
        if(event.getPlayer().hasPlayedBefore())
        {
            FileConfiguration config = plugin.getConfig();
            String joinMessage = config.getString("join-message-has-played-before");
            joinMessage = joinMessage.replace("%player%", playerName);
            event.setJoinMessage(joinMessage);
        }
        else
        {
            FileConfiguration config = plugin.getConfig();
            String joinMessage = config.getString("join-message-has-not-played-before");
            joinMessage = joinMessage.replace("%player%", playerName);
            event.setJoinMessage(joinMessage);
        }
    }

    private boolean isPlayerBanned(String playerName) {
        try (Connection connection = SQLiteConnector.getConnection();
             PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM bans WHERE player_name = ?")) {
            statement.setString(1, playerName);

            try (ResultSet resultSet = statement.executeQuery()) {
                if (resultSet.next()) {
                    int count = resultSet.getInt(1);
                    return count > 0;
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return false;
    }

    private BanInfo getBanInfo(String playerName) {
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try{
            Connection connection = SQLiteConnector.getConnection();

            if (connection == null || connection.isClosed()) {
                throw new SQLException("Database connection is null or closed.");
            }

            statement = connection.prepareStatement("SELECT * FROM bans WHERE player_name = ?");
            statement.setString(1, playerName);

            resultSet = statement.executeQuery();

            if (resultSet.next()) {
                String staffMember = resultSet.getString("staff_member");
                String reason = resultSet.getString("reason");

                return new BanInfo(playerName, staffMember, reason);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (resultSet != null) {
                    resultSet.close();
                }
                if (statement != null) {
                    statement.close();
                }
                // Note: Do not close the connection here to keep it open for later use
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private String getKickMessage(BanInfo banInfo) {
        if (banInfo != null) {
            return ChatColor.RED + "You are banned from this server.\n" +
                    ChatColor.RED + "Banned by: " + ChatColor.YELLOW + banInfo.getStaffMember() + "\n" +
                    ChatColor.RED + "Reason: " + ChatColor.YELLOW + banInfo.getReason();
        } else {
            return ChatColor.RED + "You are banned from this server.";
        }
    }

Here is the SQLConnector code:

    private static Connection connection;

    public static Connection getConnection() {
        if(connection == null) {
            try {
                Class.forName("org.sqlite.JDBC");
                connection = DriverManager.getConnection("jdbc:sqlite:plugins/Jellyfish-Hosting-Plugin/punishments.db");
            } catch (ClassNotFoundException | SQLException e) {
                e.printStackTrace();
            }
        }
        return connection;
    }

    public static void closeConnection() {
        try {
            if (connection != null && !connection.isClosed()) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

The error that I receive is (half of):

[22:20:03 WARN]: java.sql.SQLException: Database connection is null or closed.
[22:20:03 WARN]:        at plugin-1.0-beta.jar//xyz.jellyfishhosting.plugin.events.JoinEvent.getBanInfo(JoinEvent.java:82)
[22:20:03 WARN]:        at plugin-1.0-beta.jar//xyz.jellyfishhosting.plugin.events.JoinEvent.onPlayerJoin(JoinEvent.java:35)
[22:20:03 WARN]:        at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor1.execute(Unknown Source)
[22:20:03 WARN]:        at org.bukkit.plugin.EventExecutor$2.execute(EventExecutor.java:77)
[22:20:03 WARN]:        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:81)
[22:20:03 WARN]:        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70)
[22:20:03 WARN]:        at io.papermc.paper.plugin.manager.PaperEventManager.callEvent(PaperEventManager.java:54)
[22:20:03 WARN]:        at io.papermc.paper.plugin.manager.PaperPluginManagerImpl.callEvent(PaperPluginManagerImpl.java:126)
[22:20:03 WARN]:        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:615)
[22:20:03 WARN]:        at net.minecraft.server.players.PlayerList.a(PlayerList.java:346)
[22:20:03 WARN]:        at net.minecraft.server.network.ServerConfigurationPacketListenerImpl.a(ServerConfigurationPacketListenerImpl.java:130)
[22:20:03 WARN]:        at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:18)
[22:20:03 WARN]:        at net.minecraft.network.protocol.configuration.ServerboundFinishConfigurationPacket.a(ServerboundFinishConfigurationPacket.java:9)
[22:20:03 WARN]:        at net.minecraft.network.protocol.PlayerConnectionUtils.lambda$ensureRunningOnSameThread$0(PlayerConnectionUtils.java:53)

I have tried using normal debug statements to find out where it was closing at which seems to be after the checking to see if the player is banned or not.

1

There are 1 best solutions below

1
Jelly Fish On

I managed to fix the issue myself and here is how. So the main problem was where I was checking to see if the member was banned in the first place. The connection wasn't really closing / opening properly hence causing the error later on. Here is the updated isPlayerBanned code:

    private boolean isPlayerBanned(String playerName) {
        try{
            Connection connection = SQLiteConnector.getConnection();
            PreparedStatement statement = connection.prepareStatement("SELECT COUNT(*) FROM bans WHERE player_name = ?");
            statement.setString(1, playerName);
            try(ResultSet resultSet = statement.executeQuery()) {
                if(resultSet.next()) {
                    int count = resultSet.getInt(1);
                    return count > 0;
                }
            }
            connection.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }

        return false;
    }