I've hosted a MySQL DB in a webserver. I've granted all privledges and allowed my IP to connect to this database remotely from my local computer. It gets connected and I'm able to retrieve data from the database to my Java Swing application. But, sometimes I get this error message and my connection with the hosted DB fails.
Error is shows below:
Apr 7, 2012 12:49:20 AM scm.new_fas txtSearchKeyReleased
SEVERE: null
com.mysql.jdbc.CommunicationsException: Communications link failure due to underlying exception:
** BEGIN NESTED EXCEPTION **
java.io.EOFException
MESSAGE: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
STACKTRACE:
java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:1997)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2411)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3250)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3179)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1207)
at scm.DBControl.getResult(DBControl.java:49)
at scm.new_fas.txtSearchKeyReleased(new_fas.java:1686)
at scm.new_fas.access$2300(new_fas.java:28)
at scm.new_fas$23.keyReleased(new_fas.java:1136)
at java.awt.Component.processKeyEvent(Component.java:5999)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2794)
at java.awt.Component.processEvent(Component.java:5815)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:693)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:958)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:830)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:657)
at java.awt.Component.dispatchEventImpl(Component.java:4282)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
** END NESTED EXCEPTION **
Last packet sent to the server was 2 ms ago.
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2622)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2916)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1723)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3250)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3179)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1207)
at scm.DBControl.getResult(DBControl.java:49)
at scm.new_fas.txtSearchKeyReleased(new_fas.java:1686)
at scm.new_fas.access$2300(new_fas.java:28)
at scm.new_fas$23.keyReleased(new_fas.java:1136)
at java.awt.Component.processKeyEvent(Component.java:5999)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2794)
at java.awt.Component.processEvent(Component.java:5815)
at java.awt.Container.processEvent(Container.java:2058)
at java.awt.Component.dispatchEventImpl(Component.java:4410)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:693)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:958)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:830)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:657)
at java.awt.Component.dispatchEventImpl(Component.java:4282)
at java.awt.Container.dispatchEventImpl(Container.java:2116)
at java.awt.Window.dispatchEventImpl(Window.java:2429)
at java.awt.Component.dispatchEvent(Component.java:4240)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Can somebody please help me with this situation. I dont understand whats wrong! Is it the server or ?
Thanks a lot :)
This is my class to Connect the DB:
package scm;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DBControl {
private static DBControl con;
private static String severIp = null;
private static String severPort = null;
private static String userName = null;
private static String password = null;
private static ResultSet rs = null;
private static Connection cc = null;
public DBControl() {
}
public static synchronized DBControl getInstance() {
if (con == null) {
con = new DBControl();
}
return con;
}
public void setSeverIp(String Ip) {
severIp = Ip;
}
public void setSeverPort(String Port) {
severPort = Port;
}
public void SetUserName(String Name) {
userName = Name;
}
public void setPassword(String passWord) {
password = passWord;
}
public static ResultSet getResult(String url) throws Exception {
Statement s = cc.createStatement();
rs = s.executeQuery(url);
return rs;
}
public static Connection getConnection() throws Exception {
// try {
Class.forName("com.mysql.jdbc.Driver");
cc = (Connection) DriverManager.getConnection("jdbc:mysql://" + getSeverIp() + ":" + getSeverPort() + "/anuradha_rr", getUserName(), getPassword());
return cc;
}
public void setResult(String url) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
cc = (Connection) DriverManager.getConnection("jdbc:mysql://" + getSeverIp() + ":" + getSeverPort() + "/anuradha_rr", getUserName(), getPassword());
Statement s = (Statement) cc.createStatement();
s.executeUpdate(url);
}
public static String getSeverIp() {
return severIp;
}
public static String getSeverPort() {
return severPort;
}
public static String getUserName() {
return userName;
}
public static String getPassword() {
return password;
}
}
Make sure you are not using a dead jdbc connection. Depending on how you are creating your jdbc connection they may be going idle. If you are using the same connection over and over, test the connection before you try to issue a query and get a new one if it has been closed by mysql.
UPDATE:
You create a new connection everywhere except getResult() which is where the stack trace identifies the error comes from. You can either create a new connection like you do everywhere else, or improve the encapsulation of getConnection(). In other words, change getConnection() to return the static Connection stored in your class, on condition it is not null and still valid. Otherwise create a new connection and return that.
This is a fairly common problem in MySQL, unfortunately occurring usually only after in production when application runs for some extended time unlike in the short development cycle.
MySQL closes connections without notifying its clients and the not much telling exception is what appears when you try to use a timed out connection. you could for example ping the connection with some trivial SQL statement periodically to avoid timeout.
It is a good practice to use a connection pool (to avoid problem with too many users accessing the DB at once), e.g. DBCP, in general. DBCP may be added to your application easily and you only set it as a quasi JDBC driver.
There you can set things proper way.
I copied this DBCP config from one of my projects:
MaxActive=20,
MaxWait=60000,
TestWhileIdle=true,
TimeBetweenEvictionRunsMillis=300000,
MinEvictableIdleTimeMillis=300000,
TestOnBorrow=true,
ValidationQuery='SELECT 1'
Update:
As a very simple solution, you could try catching the exception on access and open a new connection in that case.
Related
This question already has answers here:
Connect Java to a MySQL database
(14 answers)
Closed 4 years ago.
I'm having issues connecting to an external IP address using JDBC. When I execute the following code, I get this error No suitable driver found for jdbc:mysql://52.206.157.109:3306/U054Jk
Code:
package util;
import java.sql.*;
public class db {
private static String server = "52.206.157.109";
private static String dbName = "U054Jk";
private static String userName = "secret";
private static String password = "secret";
private static Connection getCon() throws SQLException {
String host = "jdbc:mysql://" + server + ":3306/" + dbName;
Connection conn = DriverManager.getConnection(
host,
userName,
password
);
return conn;
}
public static ResultSet ExecQuery(String query) throws SQLException {
//Get the connection
Connection conn = getCon();
//Create the statement
Statement stmt = conn.createStatement();
//Execute the statement
ResultSet rs = stmt.executeQuery(query);
//Return ResultSet
return rs;
}
}
I can connect with my SQL client just fine using the credentials but can't quite figure out the JDBC string that I need for the URL. Thank you for your help.
Please add MySQL Connector in the classpath. Your project needs a JDBC driver implementing the interfaces of JDBC.
If you are using Apache Maven, add the following in the pom.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
Or else, download the jar from the link and add it to the classpath.
I am trying to set up a remote Derby database just for practice. The following code works without a problem whenever I access the DB on my harddrive:
class Test{
public static void main(String[] args) {
String protocol = "jdbc:derby:";
// String dbPath = "C:/Java_Practice/derbyDB"; // this dbPath works...
String dbPath = "//108.167.141.127/derbyDB"; // and this one doesn't
String url = protocol + dbPath;
try( Connection conn = DriverManager.getConnection(url) )
{
System.out.println(conn);
}
catch(SQLException e){
System.out.println(e.getMessage());
}
}
}
I then uploaded the whole derbyDB directory to my Hostgator-hosted website, obtained its IP by pinging the server and edited the dbPath var accordingly. The code stopped working as if it can't even see the DB. What am I missing?
Looks like your driver class not loaded.
Try loading it before calling DriverManager.getConnection, and see if it works.
String driver = "org.apache.derby.jdbc.ClientDriver";
Class.forName(driver).newInstance();
String protocol = "jdbc:derby:";
String dbPath = "//108.167.141.127/derbyDB"+";create=true";
String url = protocol + dbPath;
Connection conn = DriverManager.getConnection(url);
Answering my own question after some digging.
This is what I found in the official Apache Derby documentation (https://db.apache.org/derby/docs/10.0/manuals/develop/develop14.html):
You can specify only databases that are local to the machine on which
the JVM is running.
Looks like what I wanted to accomplish cannot be done...
I have been learning how to get SQL Derby installed and running, and I looked at google and didn't find anything useful that could fix this problem. In the line: Connection getConnection() I get the error: "Illegal modifier for parameter getConnection; only final is permitted" What is wrong? It gives me the same error even if I move the code over to a different class. It is derby on eclipse in java, and I did everything in creating and connecting the database. I have not imported any reference libraries or software pluggins. I updated the DTP. I used the vogella tutorial for databases and eclipse. I have also installed Derby several times over the course of a couple months, but never seem to be able to get a separate java project to connect properly. Once again, my issue is the getConnection giving me an error. I have a comment in the area of the problem.
import java.sql.Connection;
import java.util.Properties;
public class main {
public static void main(String[] args)
{
// TODO Auto-generated method stub
//******************************************************
//The issue is the getConnection()
public Connection getConnection() throws SQLException {
//*******************************************************
Connection conn = null;
Properties connectionProps = new Properties();
conn = DriverManager.getConnection("jdbc:derby:C:\\Users\\Josiah\\MyDB", connectionProps);
System.out.println("Connected to database");
return conn;
}
}
}
You are trying to define your getConnection method nested inside the main method - this is not allowed in Java.
Move the method to be outside of main:
public class main {
public static void main(String[] args)
{
... main method code
}
public Connection getConnection() throws SQLException {
Connection conn = null;
Properties connectionProps = new Properties();
conn = DriverManager.getConnection("jdbc:derby:C:\\Users\\Josiah\\MyDB", connectionProps);
System.out.println("Connected to database");
return conn;
}
}
I am attempting to connect to an Oracle database through Java with the Oracle JDBC driver with the following code (obscuring the host, service, user, and password):
import java.sql.*;
public class Main {
public Main () {
try {
String host = "HOST_NAME";
String port = "1521";
String service = "SERVICE_NAME";
String user = "SCHEMA_USER";
String password = "SCHEMA_PASSWORD";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = DriverManager.getConnection("jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=" +
host +
")(PORT=" +
port +
")))(CONNECT_DATA=(SERVICE_NAME=" +
service +
")))",
user,
password);
connection.close ();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main (String args) {
new Main ();
}
}
However, I receive the following error:
java.sql.SQLException: IO Error: The Network Adapter could not establish the connection
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:458)
at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:546)
at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:236)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:521)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.acxiom.axle.reporting.database.DatabaseConnection.connect(DatabaseConnection.java:23)
at com.acxiom.axle.reporting.Reporting.establishDatabaseConnection(Reporting.java:53)
at com.acxiom.axle.reporting.Reporting.beginReporting(Reporting.java:20)
at com.acxiom.axle.reporting.Entry.<init>(Entry.java:28)
at com.acxiom.axle.reporting.Entry.main(Entry.java:118)
Caused by: oracle.net.ns.NetException: The Network Adapter could not establish the connection
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:392)
at oracle.net.resolver.AddrResolution.resolveAndExecute(AddrResolution.java:434)
at oracle.net.ns.NSProtocol.establishConnection(NSProtocol.java:687)
at oracle.net.ns.NSProtocol.connect(NSProtocol.java:247)
at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:1102)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:320)
... 11 more
Caused by: java.net.UnknownHostException: null
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(Unknown Source)
at java.net.InetAddress.getAddressesFromNameService(Unknown Source)
at java.net.InetAddress.getAllByName0(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at java.net.InetAddress.getAllByName(Unknown Source)
at oracle.net.nt.TcpNTAdapter.connect(TcpNTAdapter.java:117)
at oracle.net.nt.ConnOption.connect(ConnOption.java:133)
at oracle.net.nt.ConnStrategy.execute(ConnStrategy.java:370)
... 16 more
The strange thing is, I can connect to the database from PL/SQL Developer, I can ping the remote host, and I can telnet to the remote host on port 1521.
Why would only Java appear to give an UnknownHostException, but I can connect and ping the host with other applications?
EDIT: I removed "hr/hr" from the connection string above. I have tried the connection as-is with it removed and still receive the same error. I've also tried changing the connection string to match the version morgano listed in his answer, with the same result. Finally, I tried to change the port number to a port I know it's not listening on, and it still receives the same error.
The connection string is of the correct format. The problem is that the host isn't set. It's null, or perhaps the string "null". There's simply no other way to generate the error message java.net.UnknownHostException: null
In your sample code, you write String host = "HOST_NAME";. This makes it look like in your real code you are assigning a constant string to the variable host. However, I'm going to stick my neck out and say that in your real code you are not doing this. You are looking up the host name from somewhere, this lookup fails for some reason, you don't check this, and hence you pass a null value into the connection string.
Your JDBC url is wrong, according to the documentation it should be something like:
jdbc:oracle:driver_type:[username/password]#//host_name:port_number/service_name
In your case your code would be something like:
import java.sql.*;
public class Main {
public Main () {
try {
String host = "HOST_NAME";
String port = "1521";
String service = "SERVICE_NAME";
String user = "SCHEMA_USER";
String password = "SCHEMA_PASSWORD";
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:#//" + host
+ ":" + port + "/" + service, user, password);
connection.close ();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main (String args) {
new Main ();
}
}
I am having problems remotely connecting to my mySQL database in Java. Here is my error message:
java.sql.SQLException: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified
I am sure my ip address & port I am using work, since I am using the same ip & port for a mySQL client program.
My hosting company do not support JDBC so I am using a JDBC-ODBC bridge.
Here is my class:
public class SQLdataBase {
private Connection con;
private Statement st;
private static final String url="jdbc:odbc://xxx.xxx.xxx.xxx:3306";
private static final String className="sun.jdbc.odbc.JdbcOdbcDriver";
private static String user;
private static String pass;
SQLdataBase(String userName, String password) {
user=userName;
pass=password;
try {
Class.forName(className);
con = DriverManager.getConnection(url, user, pass);
System.out.println("success");
st = con.createStatement();
} catch (Exception ex) {
System.out.println(ex);
}
//do whatever database processing is required
}
public void queryNoReturn(String query) throws SQLException{
st.executeQuery(query);
}
}
The error occures at this line:
con = DriverManager.getConnection(url, user, pass);
What am I doing wrong?
String url="jdbc:odbc://xxx.xxx.xxx.xxx:3306";
In ODBC, you normally use the data source name (DSN) instead of hostname:port in URL. If this is unclear and/or not directly revealable in the documentation of the hosting, then you'll need to contact them for the exact DSN. Once known, then use the following URL:
String url="jdbc:odbc:dataSourceName";