# Bukkit Plugin Problem



## MR_UNIX (27. Okt 2012)

Hallo Community,

ich arbeite zurzeit an einem Bukkit-Plugin, welches Kommandos aus einer MySQL-Tabelle auslesen soll.
Dabei bekomme ich nun immer folgende Fehlermeldung:


```
18:42:35 [SEVERE] java.sql.SQLException: The url cannot be null
18:42:35 [SEVERE]       at java.sql.DriverManager.getConnection(Unknown Source)
18:42:35 [SEVERE]       at java.sql.DriverManager.getConnection(Unknown Source)
18:42:35 [SEVERE]       at de.mrpixeldream.mysqlreader.SQLConnector.connect(SQLC
onnector.java:99)
18:42:35 [SEVERE]       at de.mrpixeldream.mysqlreader.HandlerTask.run(HandlerTa
sk.java:41)
18:42:35 [SEVERE]       at org.bukkit.craftbukkit.scheduler.CraftTask.run(CraftT
ask.java:53)
18:42:35 [SEVERE]       at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainT
hreadHeartbeat(CraftScheduler.java:345)
18:42:35 [SEVERE]       at net.minecraft.server.MinecraftServer.q(MinecraftServe
r.java:510)
18:42:35 [SEVERE]       at net.minecraft.server.DedicatedServer.q(DedicatedServe
r.java:213)
18:42:35 [SEVERE]       at net.minecraft.server.MinecraftServer.p(MinecraftServe
r.java:474)
18:42:35 [SEVERE]       at net.minecraft.server.MinecraftServer.run(MinecraftSer
ver.java:406)
18:42:35 [SEVERE]       at net.minecraft.server.ThreadServerApplication.run(Sour
ceFile:539)
```

Auf den ersten Blick sieht es so aus, als ob ich keinen Server übergeben hätte, zu dem sich der Task verbinden soll. Dies kann aber nicht sein, da ich die Server-URL selbst übergeben habe.
Hier der Code meiner MySQL-Verbindungsklasse:


```
package de.mrpixeldream.mysqlreader;

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

public class SQLConnector
{
	private boolean		isInitialized;
	private boolean		isConnected;
	private boolean 	isFailed;

	private String		server;
	private String		user;
	private String		password;
	private String		database;

	private Connection	con;
	private Statement	stmt;
	private ResultSet	result;

	public SQLConnector()
	{
		try
		{
			Class.forName("com.mysql.jdbc.Driver");
		}
		catch (ClassNotFoundException e)
		{
			// TODO Automatisch generierter Erfassungsblock
			e.printStackTrace();
		}
		
		isInitialized = false;
		isConnected = false;
		isFailed = false;
	}

	public SQLConnector(String server, String user, String password, String database)
	{
		isInitialized = true;
		isConnected = false;
		
		this.user = user;
		this.password = password;
		this.database = database;

		if (!server.startsWith("jdbc:mysql://"))
		{
			server = ( "jdbc:mysql://" + server + "/" + database);
		}

		try
		{
			con = DriverManager.getConnection(server, user, password);
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			if (e.getMessage().contains("denied"))
			{
				System.err.println("[MySQL-Reader] CAN'T CONNECT! WRONG USER AND/OR PASSWORD!");
				isFailed = true;
				return;
			}
			
			return;
		}
		
		try
		{
			stmt = con.createStatement();
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			System.err.println("[MySQL-Reader] AN UNKNOWN ERROR OCCURRED!");
			isFailed = true;
			return;
		}
		
		isFailed = false;
		isConnected = true;
		return;
	}
	
	public boolean connect()
	{
		if (isConnected || isFailed || !isInitialized)
		{
			return false;
		}
		else
		{
			try
			{
				con = DriverManager.getConnection(server, user, password);
			}
			catch (SQLException e)
			{
				e.printStackTrace();
				if (e.getMessage().contains("denied"))
				{
					System.err.println("[MySQL-Reader] CAN'T CONNECT! WRONG USER AND/OR PASSWORD!");
					isFailed = true;
					return false;
				}
				if (e.getMessage().contains("refused"))
				{
					System.err.println("[MySQL-Reader] CAN'T CONNECT! SERVER NOT AVAILABLE!");
					isFailed = true;
					return false;
				}
				
				return false;
			}
			
			return true;
		}
	}
	
	public boolean disconnect()
	{
		if (!isConnected || isFailed || !isInitialized)
		{
			return false;
		}
		else
		{
			try
			{
				con.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
				System.err.println("[MySQL-Reader] CAN'T CLOSE CONNECTION!");
				e.printStackTrace();
				return false;
			}
			con = null;
			
			return true;
		}
	}
	
	public void init(String server, String user, String password, String database)
	{
		isInitialized = true;
		isConnected = false;

		if (!server.startsWith("jdbc:mysql://"))
		{
			server = ( "jdbc:mysql://" + server );
		}
		
		this.user = user;
		this.password = password;
		this.database = database;
	}
	
	public ResultSet query(String sql_query)
	{
		if (!isInitialized || isFailed || !isConnected)
		{
			System.err.println("[MySQL-Reader] NO CONNECTION FOUND!");
			System.err.println("[MySQL-Reader] Fail: " + isFailed);
			System.err.println("[MySQL-Reader] Connection: " + isConnected);
			System.err.println("[MySQL-Reader] Init: " + isInitialized);
			return null;
		}
		
		try
		{
			stmt = con.createStatement();
		}
		catch (SQLException e1)
		{
			e1.printStackTrace();
		}
		
		try
		{
			return this.stmt.executeQuery(sql_query);
		}
		catch (SQLException e)
		{
			System.err.println("[MySQL-Reader] CAN'T EXECUTE QUERY! ERROR:");
			e.printStackTrace();
			return null;
		}
	}
}
```

Als Server übergebe ich "mrpixeldream.de". Als Passwort und User die von mir eingestellten Daten des Servers.
Hat jemand eine Idee, woran das liegen kann?

Danke schon einmal im Voraus!


----------



## Marcinek (27. Okt 2012)

Wie rufst Du die klasse auf?


----------



## MR_UNIX (27. Okt 2012)

Über


```
SQLConnector connector = new SQLConnector();
connector.init("mrpixeldream.de", "user", "password");
connector.connect();
connector.query("SELECT * FROM bukkit;");
```


----------



## Marcinek (27. Okt 2012)

Hier fehlt wohl ein this.


```
server = ( "jdbc:mysql://" + server );
```


----------



## Tomate_Salat (27. Okt 2012)

Abgesehen von dem fehlenden [c]this[/c]. 
Laufen Bukkit + MySQL auf dem gleichem Server? MySQL ist afaik standardmäßig so eingestellt, dass es keine Verbindungen von außen zulässt. Das müsstest du bei unterschiedlichen Servern ggf. noch einstellen ... sofern du es kannst/notwendigen Berechtigungen hast.


----------



## MR_UNIX (28. Okt 2012)

Hallo,

ich teste mal die Sache mit dem "this". Klingt auf jeden Fall logisch. Jetzt weiß ich auch, warum man Methoden-Parameter immer final machen sollte 

Der MySQL-Server ist extern aber auch so eingerichtet, dass externe Zugriffe auf die entsprechende DB erlaubt werden.


----------



## MR_UNIX (28. Okt 2012)

Okay. So weit, so gut.

Das mit dem "this" hat etwas gebracht. Ich bekomme jetzt nicht mehr die Meldung mit "URL cannot be null".
Anstatt dessen kommt jetzt folgende Meldung:


```
15:24:16 [SEVERE] java.sql.SQLException: Access denied for user 'carpetsql9'@'95
.119.57.234' (using password: YES)
15:24:16 [SEVERE]       at com.mysql.jdbc.SQLError.createSQLException(SQLError.j
ava:1073)
15:24:16 [SEVERE]       at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
3593)
15:24:16 [SEVERE]       at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
3525)
15:24:16 [SEVERE]       at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:
931)
15:24:16 [SEVERE]       at com.mysql.jdbc.MysqlIO.secureAuth411(MysqlIO.java:403
1)
15:24:16 [SEVERE]       at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1296)

15:24:16 [SEVERE]       at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionI
mpl.java:2338)
15:24:16 [SEVERE]       at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(Conne
ctionImpl.java:2371)
15:24:16 [SEVERE]       at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionI
mpl.java:2163)
15:24:16 [SEVERE]       at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.j
ava:794)
15:24:16 [SEVERE]       at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection
.java:47)
15:24:16 [SEVERE]       at sun.reflect.NativeConstructorAccessorImpl.newInstance
0(Native Method)
15:24:16 [SEVERE]       at sun.reflect.NativeConstructorAccessorImpl.newInstance
(Unknown Source)
15:24:16 [SEVERE]       at sun.reflect.DelegatingConstructorAccessorImpl.newInst
ance(Unknown Source)
15:24:16 [SEVERE]       at java.lang.reflect.Constructor.newInstance(Unknown Sou
rce)
15:24:16 [SEVERE]       at com.mysql.jdbc.Util.handleNewInstance(Util.java:407)
15:24:16 [SEVERE]       at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionI
mpl.java:378)
15:24:16 [SEVERE]       at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegist
eringDriver.java:305)
15:24:16 [SEVERE]       at java.sql.DriverManager.getConnection(Unknown Source)
15:24:16 [SEVERE]       at java.sql.DriverManager.getConnection(Unknown Source)
15:24:16 [SEVERE]       at de.mrpixeldream.mysqlreader.SQLConnector.connect(SQLC
onnector.java:101)
15:24:16 [SEVERE]       at de.mrpixeldream.mysqlreader.HandlerTask.run(HandlerTa
sk.java:41)
15:24:16 [SEVERE]       at org.bukkit.craftbukkit.scheduler.CraftTask.run(CraftT
ask.java:53)
15:24:16 [SEVERE]       at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainT
hreadHeartbeat(CraftScheduler.java:345)
15:24:16 [SEVERE]       at net.minecraft.server.MinecraftServer.q(MinecraftServe
r.java:510)
15:24:16 [SEVERE]       at net.minecraft.server.DedicatedServer.q(DedicatedServe
r.java:213)
15:24:16 [SEVERE]       at net.minecraft.server.MinecraftServer.p(MinecraftServe
r.java:474)
15:24:16 [SEVERE]       at net.minecraft.server.MinecraftServer.run(MinecraftSer
ver.java:406)
15:24:16 [SEVERE]       at net.minecraft.server.ThreadServerApplication.run(Sour
ceFile:539)
```

Wobei auch hier der erste Eindruck täuscht. Ich greife NICHT mit falschem User oder Passwort auf den Server zu sondern die MySQL-Klasse führt anscheinend einen Fallback auf den eigenen Rechner durch. Die IP, auf die er sich oben verbinden möchte ist die, die mir Wie ist meine IP-Adresse? für meinen lokalen Rechner ausgibt. Er löst also die übergebene URL "mrpixeldream.de" falsch oder gar nicht auf.

Mein jetziger MySQL-Code:


```
package de.mrpixeldream.mysqlreader;

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

public class SQLConnector
{
	private boolean		isInitialized;
	private boolean		isConnected;
	private boolean 	isFailed;

	private String		server;
	private String		user;
	private String		password;
	private String		database;

	private Connection	con;
	private Statement	stmt;
	private ResultSet	result;

	public SQLConnector()
	{
		try
		{
			Class.forName("com.mysql.jdbc.Driver");
		}
		catch (ClassNotFoundException e)
		{
			// TODO Automatisch generierter Erfassungsblock
			e.printStackTrace();
		}
		
		isInitialized = false;
		isConnected = false;
		isFailed = false;
	}

	public SQLConnector(String server, String user, String password, String database)
	{
		isInitialized = true;
		isConnected = false;
		
		this.user = user;
		this.password = password;
		this.database = database;

		if (!server.startsWith("jdbc:mysql://"))
		{
			server = ( "jdbc:mysql://" + server + "/" + database);
		}
		
		this.server = server;

		try
		{
			con = DriverManager.getConnection(server, user, password);
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			if (e.getMessage().contains("denied"))
			{
				System.err.println("[MySQL-Reader] CAN'T CONNECT! WRONG USER AND/OR PASSWORD!");
				isFailed = true;
				return;
			}
			
			return;
		}
		
		try
		{
			stmt = con.createStatement();
		}
		catch (SQLException e)
		{
			e.printStackTrace();
			System.err.println("[MySQL-Reader] AN UNKNOWN ERROR OCCURRED!");
			isFailed = true;
			return;
		}
		
		isFailed = false;
		isConnected = true;
		return;
	}
	
	public boolean connect()
	{
		if (isConnected || isFailed || !isInitialized)
		{
			return false;
		}
		else
		{
			try
			{
				con = DriverManager.getConnection(server, user, password);
			}
			catch (SQLException e)
			{
				e.printStackTrace();
				if (e.getMessage().contains("denied"))
				{
					System.err.println("[MySQL-Reader] CAN'T CONNECT! WRONG USER AND/OR PASSWORD!");
					isFailed = true;
					return false;
				}
				if (e.getMessage().contains("refused"))
				{
					System.err.println("[MySQL-Reader] CAN'T CONNECT! SERVER NOT AVAILABLE!");
					isFailed = true;
					return false;
				}
				
				return false;
			}
			
			return true;
		}
	}
	
	public boolean disconnect()
	{
		if (!isConnected || isFailed || !isInitialized)
		{
			return false;
		}
		else
		{
			try
			{
				con.close();
			}
			catch (SQLException e)
			{
				e.printStackTrace();
				System.err.println("[MySQL-Reader] CAN'T CLOSE CONNECTION!");
				e.printStackTrace();
				return false;
			}
			con = null;
			
			return true;
		}
	}
	
	public void init(String server, String user, String password, String database)
	{
		isInitialized = true;
		isConnected = false;
		
		this.user = user;
		this.password = password;
		this.database = database;

		if (!server.startsWith("jdbc:mysql://"))
		{
			server = ( "jdbc:mysql://" + server + "/" + database);
		}
		
		this.server = server;
	}
	
	public ResultSet query(String sql_query)
	{
		if (!isInitialized || isFailed || !isConnected)
		{
			System.err.println("[MySQL-Reader] NO CONNECTION FOUND!");
			System.err.println("[MySQL-Reader] Fail: " + isFailed);
			System.err.println("[MySQL-Reader] Connection: " + isConnected);
			System.err.println("[MySQL-Reader] Init: " + isInitialized);
			return null;
		}
		
		try
		{
			stmt = con.createStatement();
		}
		catch (SQLException e1)
		{
			e1.printStackTrace();
		}
		
		try
		{
			return this.stmt.executeQuery(sql_query);
		}
		catch (SQLException e)
		{
			System.err.println("[MySQL-Reader] CAN'T EXECUTE QUERY! ERROR:");
			e.printStackTrace();
			return null;
		}
	}
}
```

Ich würde mich sehr freuen, wenn wir auch dieses Problem lösen könnten


----------



## Marcinek (28. Okt 2012)

Dein User hat keinen externen Zugriff auf die MYSQL DB.

Oder Username und Passwort sind falsch. Google mal die Fehlermeldung.


----------



## MR_UNIX (28. Okt 2012)

MR_UNIX hat gesagt.:


> Der MySQL-Server ist extern aber auch so eingerichtet, dass externe Zugriffe auf die entsprechende DB erlaubt werden.





MR_UNIX hat gesagt.:


> Wobei auch hier der erste Eindruck täuscht. Ich greife NICHT mit falschem User oder Passwort auf den Server zu sondern die MySQL-Klasse führt anscheinend einen Fallback auf den eigenen Rechner durch. Die IP, auf die er sich oben verbinden möchte ist die, die mir Wie ist meine IP-Adresse? für meinen lokalen Rechner ausgibt. Er löst also die übergebene URL "mrpixeldream.de" falsch oder gar nicht auf.



Bitte komplett lesen! Der externe Zugriff ist vorhanden UND auch die Zugangsdaten sind korrekt! Es geht um die IP!


----------



## Marcinek (28. Okt 2012)

MR_UNIX hat gesagt.:


> Bitte komplett lesen! Der externe Zugriff ist vorhanden UND auch die Zugangsdaten sind korrekt! Es geht um die IP!



Nein hat er nicht. Zumindest nicht von beliebigen Host.

Schau mal in die MySQL-DB und zeig mal die Einträge des Users.


----------



## MR_UNIX (28. Okt 2012)

Doch. Hat er. Es geht um die IP!


----------



## Marcinek (28. Okt 2012)

OK, mach wie du willst


----------



## MR_UNIX (28. Okt 2012)

Ja lies doch bitte den Post bis zum Ende. Die Daten sind richtig und auch der externe Zugriff von jedem Host erlaubt.
Habe extra nochmal den Support angeschrieben!


----------



## gman (28. Okt 2012)

> Access denied for user 'carpetsql9'@'95.119.57.234'



Ich denke das ist so richtig, weil es ja bedeutet: "User 'carpetsql9' vom Rechner '95.119.57.234'".

Versuch doch vielleicht mal dich mit einem anderen Client eine Verbindung zur DB
aufzubauen (MySQL-Kommandozeile, SQL-Developer, Eclipse, Netbeans, ...).


----------



## MR_UNIX (28. Okt 2012)

Hab ich. Wie gesagt, er versucht wohl ein Fallback auf den lokalen Rechner, obwohl der Server erreichbar ist.
Über Kommandozeile geht alles ^^


----------



## Marcinek (28. Okt 2012)

1) So einen Fallback gibt es nicht.

2) Wenn du nicht die entsprechenden Ports FF hast im Router würde eine connection refuse passieren und nicht sowas.

==> Der User hat keinen Zugriff von extern.


----------



## gman (28. Okt 2012)

> er versucht wohl ein Fallback auf den lokalen Rechner



Nochmal: "User 'carpetsql9' *vom* Rechner '95.119.57.234'"

Er verbindet sich nicht mit der IP, er zeigt die IP von dem Rechner an der versucht
sich zu verbinden.



> Über Kommandozeile geht alles



Wenn du die Kommandozeile auf deinem lokalen Rechner nutzt funktioniert es?


----------



## MR_UNIX (28. Okt 2012)

Ja. Und wie gesagt: die IP, welche er nutzen will ist meine lokale, obwohl ich als Verbindungs-Ziel "mrpixeldream.de" angegeben habe, was auf einer anderen IP (176.9.37.48) läuft.
Das ist ja das, was ich nicht verstehe! Er versucht, eine Verbindung zu meinem lokalen Rechner herzustellen.

// EDIT: Ahhh  ich glaube ich verstehe, was ihr mir sagen wollt! Die IP, die er ausgibt ist die, von WO man sich verbinden will, nicht wohin?
Wenn ja: Sorry, das hab' ich nicht verstanden!
Aber trotzdem ist das Problem: Externer Zugriff ist eingerichtet 

// EDIT 2: Richtig lesen sollte auch ich 
Hab's grad gesehen, dass du - gman - genau das geschrieben hast xD


----------



## gman (28. Okt 2012)

Ok, ein Problem haben wir schonmal beseitigt ;-)

Wie ist es mit der Kommandozeilenverbindung? Klappt die vom lokalem Rechner?

Wenn ja, würde ich mal gucken ob du für die MySQL-Version auch den richtigen
Treiber nutzt. Ich habe gehört das MySQL da manchmal zickig/wählerisch sein kann.


----------



## MR_UNIX (29. Okt 2012)

Die Kommandozeilen-Verbindung funktioniert ausgezeichnet! Auch vom gleichen Rechner wo das Plugin läuft. Und die Treiber sollten auch kein Problem sein, da ich die Verbindung ja über den DriverManager aufbaue, welcher ja den passenden Treiber zur URL raussucht und zusätzlich lade ich ja zur Sicherheit den JDBC-MySQL Treiber als Fallback-Treiber.


----------



## gman (29. Okt 2012)

> welcher ja den passenden Treiber zur URL raussucht



Hmmja... Mit [c]Class.forName("com.mysql.jdbc.Driver");[/c] gibst du den Treiber an.
Dazu muss natürlich die passende Jar-Datei vorhanden sein. Und deren Version sollte
zu der Version der Datenbank passen.

Welche Version von MySQL verwendest du?

Welche Version vom Treiber verwendest du?


----------



## Marcinek (29. Okt 2012)

Welche Fehlermeldung bearbeiten wir hier?

Wie hast du dich alternativ zur Datenbank verbunden?


----------



## MR_UNIX (1. Nov 2012)

Keine Ahnung, woran genau es jetzt lag aber ich habe es hinbekommen. Werde die Tage mal den neuen Code posten. Vielleicht findet ihr ja den Unterschied ^^

Danke für die Hilfe


----------

