Null Pointer Exception Mysql

Discussion in 'Spigot Plugin Development' started by Bukkit-Galore, Jul 10, 2018.

  1. Hi, can someone please inspect my code and work out why I get a null pointer exception when I call mysql.getConnection() from a different class. The internal getConnection works as it returns the checks for the database accessible and table exists. The error is a null pointer exception for getConnection() on this line of code in PlayerStatements:
    Code (Java):
    PreparedStatement statement = mysql.getConnection().prepareStatement("SELECT * FROM " + mysql.getBankAccountsTable() + " WHERE UUID=?");
    Any help is much appreciated :D

    MySQL Class:

    Code (Java):
    package net.Helixcraft.BankVault.Database.MySQL;

    import java.sql.Connection;
    import java.sql.DatabaseMetaData;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;

    import net.Helixcraft.BankVault.BankVault;


    public class MySQL
    {
        private BankVault plugin = (BankVault) BankVault.getPlugin(BankVault.class);

        public static final String ANSI_RESET = "\033[0m";
        public static final String ANSI_GREEN = "\033[32m";
        public static final String ANSI_RED = "\033[31m";
        public static final String ANSI_YELLOW = "\033[33m";

        private Connection connection;
        private Boolean enabled = plugin.getDatabaseConfig().getBoolean("Database.Mysql.Enabled");
        private int port;
        private String host, database, username, password;
        private String bankAccountsTable;
        private Boolean usessl;

        public void setValues()
        {
            enabled = plugin.getDatabaseConfig().getBoolean("Database.Mysql.Enabled");
            host = plugin.getDatabaseConfig().getString("Database.Mysql.Host");
            port = plugin.getDatabaseConfig().getInt("Database.Mysql.Port");
            database = plugin.getDatabaseConfig().getString("Database.Mysql.Database");
            username = plugin.getDatabaseConfig().getString("Database.Mysql.Username");
            password = plugin.getDatabaseConfig().getString("Database.Mysql.Password");
            usessl = plugin.getDatabaseConfig().getBoolean("Database.Mysql.UseSSL");
            bankAccountsTable = plugin.getDatabaseConfig().getString("Database.Mysql.Tables.BankAccounts");
        }

        public void databaseExists()
        {
            setValues();
           
            if (enabled == true)
            {
                isDatabaseAccessable();
               
                checkTableExists(bankAccountsTable);
            }
            else
            {
                System.out.println("\033[31mDatabase: MySQL Connection Disabled\033[0m");
                return;
            }
        }

        private void isDatabaseAccessable()
        {
            try
            {
                synchronized(this)
                {
                    if ((getConnection() != null) && (!getConnection().isClosed()))
                    {
                        return;
                    }

                    Class.forName("com.mysql.jdbc.Driver");
                    DriverManager.setLoginTimeout(5);
                    setConnection(DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?autoReconnect=true&useSSL=" + usessl, username, password));

                    System.out.println("\033[32mDatabase: MySQL Connection Successful\033[0m");
                }
                return;
            }
            catch (SQLException e)
            {
                System.out.println("\033[31mDatabase: MySQL Connection Failed\033[0m");
            }
            catch (ClassNotFoundException e)
            {
                System.out.println("\033[31mDatabase: MySQL Connection Failed\033[0m");
            }
        }

        private void checkTableExists(String tableName)
        {
            try
            {
                DatabaseMetaData dbm = getConnection().getMetaData();
                ResultSet tables = dbm.getTables(null, null, tableName, null);
                if (tables.next())
                {
                  return;
                }
                else
                {
                  createTable(tableName);          
                }
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }

        private void createTable(String tableName)
        {
            String $createStatement = "CREATE TABLE `bankvault`.`accounts` (`uuid` INT NOT NULL, `playername` VARCHAR(255) NOT NULL, `balance` DOUBLE NOT NULL, PRIMARY KEY (`uuid`), UNIQUE INDEX `uuid_UNIQUE` (`uuid` ASC));";
        }

        public Connection getConnection()
        {
            return connection;
        }

        public void setConnection(Connection connection)
        {
            this.connection = connection;
            System.out.println(connection.toString());
        }

        public String getBankAccountsTable()
        {
            return bankAccountsTable;
        }
    }
    PlayerStatements Class:

    Code (Java):
    package net.Helixcraft.BankVault.Database.MySQL.Statements;

    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.UUID;

    import org.bukkit.entity.Player;

    import net.Helixcraft.BankVault.Database.MySQL.MySQL;

    public class PlayerStatements
    {
        private MySQL mysql;

        public boolean playerCheck(UUID uuid)
        {
            try
            {
                PreparedStatement statement = mysql.getConnection().prepareStatement("SELECT * FROM " + mysql.getBankAccountsTable() + " WHERE UUID=?");
               
                statement.setString(1, uuid.toString());

                ResultSet results = statement.executeQuery();
                if (results.next())
                {
                    return true;
                }
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
            return false;      
        }
       
        public void playerExists(Player player)
        {
            UUID uuid = player.getUniqueId();
           
            if(!playerCheck(uuid))
            {
                playerCreate(player);
            }
        }

        private void playerCreate(Player player)
        {
            UUID uuid = player.getUniqueId();
           
            try
            {
                PreparedStatement insert = mysql.getConnection().prepareStatement("INSERT INTO " + mysql.getBankAccountsTable() + " (uuid,playername,balance) VALUES (?,?,?)");
                insert.setString(1, uuid.toString());
                insert.setString(2, player.getName());
                insert.setInt(3, 500);
                insert.executeUpdate();
            }
            catch (SQLException e)
            {
                e.printStackTrace();
            }
        }
    }
     
     
  2. because the Connection "connection" is null. Try to initialize the connection before you run the statement.
     
  3. Please check the value of a boolean with if (boolean) {}.
    It's not necessary to check it with "true" or "false". Please change if (enabled == true) to if (enabled).
     
  4. You have to initialise mysql field or it will cause NPE (cause it's null lol)
     
  5. Don't use
    Code (Text):
    private BankVault plugin = (BankVault) BankVault.getPlugin(BankVault.class);
    write in your main class:
    Code (Text):
    public static Plugin plugin
    and in the onEnabled() function:
    Code (Text):
    plugin = this;
    Now you can access the plugin with Main.plugin (But please access it with a getter)
     
  6. Strahan

    Benefactor

    Also I see a lot of data obtained from config, but no validation of said data. That's risky.