Java MySQL - Named Pipe connection throws warning on close - java

I am connecting to MySQL in Java with Connector/J using Named Pipes. My connection and query are successful, but I am receiving a warning when I try to close the connection. I would like to know what I should do to fix whatever is causing the warning other than removing connection.close() (or removing the try-with-resources connection block and not adding a connection.close()).
Here is my code for the query:
public static List<List> QueryDB(int RowValue) {
List<Long> ValueList = new ArrayList();
try {
try (Connection Connection_T = MySQLConnectionResources.createConnection()) {
try (Statement Statement_T = Connection_T.createStatement()) {
String String_T = "SELECT AColumn FROM ATable WHERE BColumn = " + RowValue + ";";
try (ResultSet ResultSet_T = Statement_T.executeQuery(String_T)) {
while (ResultSet_T.next()) {
ValueList.add(ResultSet_T.getLong("AColumn"));
}
}
}
}
} catch(SQLException SQLException_P) {
System.err.println("ERROR: Failed to query the database.");
ValueList.clear();
}
List<List> Result_M = new ArrayList();
Result_M.add(ValueList);
return Result_M;
}
"MySQLConnectionResources" is just a custom class with method "createConnection()". There is nothing special to the class/method; it just creates and returns a connection.
After the method is completed (or technically, after the Java 7 try-with-resources connection block is completed) I receive the following error/warning:
Thu Sep 22 00:31:54 EDT 2011 WARN: Caught while disconnecting...
EXCEPTION STACK TRACE:
** BEGIN NESTED EXCEPTION **
java.net.SocketException
MESSAGE: Socket is not connected
STACKTRACE:
java.net.SocketException: Socket is not connected
at java.net.Socket.shutdownInput(Socket.java:1456)
at com.mysql.jdbc.MysqlIO.quit(MysqlIO.java:1687)
at com.mysql.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:4368)
at com.mysql.jdbc.ConnectionImpl.close(ConnectionImpl.java:1557)
at ... my class/method here (my class.java:#)
** END NESTED EXCEPTION **
If I remove the try-with-resources block (and don't add a connection.close()), the warning never appears. Also, if I switch to a TCP/IP connection the error never appears. BUT, neither of these solutions are satisfactory for my case. I want to ensure that the connection is properly closed and I will be using named pipe connections.
Any ideas?
-- (edit) --
Also: The error is being thrown by the Log within Connector/J. My error catching has nothing to do with how the error is being caught and printed. I've tried to research how to disable the WARN problems and have it print out just SEVERE problems (within Connector/J's Log), but I was unsuccessful. Furthermore, I would like to fix the WARN problem rather than ignore/conceal it.
-- (edit 2) --
I monitored the MySQL database and the connections aren't being closed. If I use a TCP/IP connection string rather than my named pipe connection string (and don't change anything else) the connection is closed just fine.
-- (edit 3) --
Ignoring my original code... just try the code below and it throws the warning. Seems like a bug to me.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public final class main {
public static void main(String[] args) {
Connection conn = null;
try {
conn =
DriverManager.getConnection("jdbc:mysql:///database?socketFactory=com.mysql.jdbc.NamedPipeSocketFactory&namedPipePath=\\\\.\\Pipe\\mysql.sock",
"root", "password");
conn.close();
} catch (SQLException ex) {
// handle any errors
}
}
}

As it appears to be a bug, I have submitted an official bug report to the MySQL bugs forum.
I will post back here whenever I receive an update.
UPDATE:
My bug report was analyzed by MySQL coders. They believe it is a JAVA bug.
Bug Report

Related

If I pass a JDBC Connection object's value to another Connection object, is only one connection open? (MySQL DB used) [duplicate]

This question already has answers here:
Difference between creating an instance variable and creating a new object in Java?
(6 answers)
Closed 6 years ago.
My method returns the value of a Connection object.
Public class DatabaseConnection
{
public Connection establishConnection(C)
{
try
{
this.readLogin(); // prompt user to enter String values for user, pass, host
this.createDatabaseIfNeeded(); // make chessleaguedb if not found
conn = DriverManager.getConnection
("jdbc:mysql://"+host+":3306/chessleaguedb", user, pass);
System.out.println("Successfully connected to chessleaguedb");
}
catch (Exception e)
{
// logic
}
return conn; // want the logic to handle opening a connection in this class and method, then pass it to a Connection object in my 'menu' class
}
}
This method is called in another class and passes the return value to a new Connection object that is used from now on.
public class DBAMenu
{
DatabaseConnection startConnection = new DatabaseConnection; // new instance of class that contains the aforementioned method establishConnection()
Connection conn = null;
conn = startConnection.establishConnection();
}
Is there only one database connection being opened here, or two, because I'm returning the value and passing it to a new Connection object?
I've tried using the NetBeans debugger, and the Connection value remains the same after this process, but admittedly I'm not 100% on the meaning of the value column in Netbeans debugger.
(Not using Java EE so can't use pooling, and can't use open source software to handle pooling as work must be my own for year 2 undergrad project)
If I pass a JDBC Connection object's value to another Connection object, is only one connection open?
You don't have 'another Connection object'. You have another reference of type Connection. Both references refer to the same object.
You have used only one connection as you have invoked conn = startConnection.establishConnection(); only once.
You need to implement close the connection, otherwise it will create connection leaks.
You can use like below:
try(Connection conn =startConnection.establishConnection()) {
//actual logic to perform db operations
} catch(SQLException sqlexe) {
//log exceptions
}
P.S.: It is not a best practice to handle connections explicitly/manually like this, rather try to implement Connection Pooling.

Overwrite existing file

I want to overwrite 2 files.
Both files store information about my in memory database (HSQLDB):
db.data and db.script
My following code should do this:
public class DBReset {
public Path db_data = Paths.get("db_sep/db_backup/db.data");
public Path db_script = Paths.get("db_sep/db_backup/db.script");
public Path dest_data = Paths.get("db_sep/db.data");
public Path dest_script = Paths.get("db_sep/db.script");
public void discard() throws IOException {
Files.copy(this.db_data, this.dest_data, StandardCopyOption.REPLACE_EXISTING);
Files.copy(this.db_script, this.dest_script, StandardCopyOption.REPLACE_EXISTING);
}
}
However if I use
public Class anotherClass {
new DBReset.discard();
// do something with DB
new DBReset.discard();
// do something other with DB
}
The second discard() does not overwrites my files.
I use discard() to reset my database to its original state. Please don't ask / tell me there are other ways to reset the database, the actual problem is why it does not overwrite my files.
Sadly SHUTDOWN does not work.
public void discard() throws IOException, SQLException {
Connection c = DBConnectFactory.getDataSource.getConnection();
PreparedStatement ps = c.preparedStatement("SHUTDOWN");
ps.executeUpdate();
ps.close();
c.close();
Files.copy(this.db_data, this.dest_data, StandardCopyOption.REPLACE_EXISTING);
Files.copy(this.db_script, this.dest_script, StandardCopyOption.REPLACE_EXISTING);
}
Throws at first line of Connection c = DBConnectFactory.getDataSource.getConnection(); java.sql.Exception: error in script file line: 1 unknown token: ... lots of Unknown Sources.
Also tested in my runQuery(String query) - that opens a connection and then executes the given query via PreparedStatement - to force the SHUTDOWN, but it throws the same error as above, where I should get a Connection at getConnection().
What I want to do is:
Restore Original DB Instance.
Do some stuff with the DB, SELECT, INSERT and then do some assertions. Basically test some stuff against the Database.
Restore Original DB Instance.
Do some other tests against the Database.
PS: I'm using HSQLDB in file mode.
It seems you do not SHUTDOWN the database. If the database is open, the .data file cannot be overwritten. Execute the SQL statement below when you finish work with the database:
SHUTDOWN
This should be executed by the program that accesses the database :
new DBReset.discard();
// do something with DB -- then perform SHUTDOWN in the same java process

Trying to connect to my sql database getting exception saying "no suitable driver found"

I'm using the tutorial at http://www.vogella.com/tutorials/MySQLJava/article.html
to try tp connect to my sql server on my server
When it executes the line:
Connection connect = DriverManager
.getConnection("jdbc:mysql:http://www.findmeontheweb.biz"
+ "user=findmeon_bitcoin&password=PASSWORD");
an exception gets thrown saying "No sutabled driver found for jdbc:mysql:http://www.findmeontheweb.biz
This is what I did
1. Downloaded the "mysql-connecter-java-5.1.33.bin.jar into my lib folder
2. added the jar to my project from preferences.
project code:
public class cStart {
private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;
public static void main (String[] args) {
int g=0;
try {
// this will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// setup the connection with the DB.
// EXCEPTION GOES OF HEAR
Connection connect = DriverManager
.getConnection("jdbc:mysql:http://www.findmeontheweb.biz"
+ "user=findmeon_bitcoin&password=PASSWORD");
} catch (Exception e) {
System.out.println("Exception...." );
}
}
}
The URL format should be look like this
jdbc:mysql://hostname/ databaseName
I think this is a much cleaner way to do it:
String URL = "jdbc:URL_TO_YOUR_DATBASE";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
As seen here: http://www.tutorialspoint.com/jdbc/jdbc-db-connections.htm
I say give that link a try with your driver. You also should make sure you have the actual jar for MySQL. It really might be invalid.
I would try the one here: http://www.java2s.com/Code/Jar/c/Downloadcommysqljdbc515jar.htm
And then add that to your project.
The URL to the database might be wrong.
If yes you should specify a correct one with including database name.
Else verify if the jdbc driver jar is added in the build-path, if yes try to put it in the lib folder of your webapp.

Special character in path to open SQLite database connection

I am trying to get a connection to a SQLite database (using Eclipse on Windows 8). Everything workes fine as long as the path name doesn't contain any special characters (like "é"). I tried to convert it to UTF-8 (because I read on http://www.sqlite.org/c3ref/open.html that it should be), but it didn't work. I get an "out of memory" exception (SQLException) what means that no database file was found.
This is the code summary of what I did:
public static String DB_PATH = "jdbc:sqlite:" + System.getProperty("user.home") + "<Rest of the path><databasename>.sqlite";
public static void main(String[] args) throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection(DB_PATH);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
// work with the database ...
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
// try to disconnect
// ...
}
Thanks for your help!
Use the latest lib from http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/

Can not read response from server

I have written a Java Program and the program connects to a database on my server, to find records, write records, update and delete. for some reason finding records works, but most of the time when i try to save or write a record it gives an error message saying:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
The last packet successfully received from the server was 9,787 milliseconds ago. The last packet sent successfully to the server was 8,183 milliseconds ago.
Caused by: 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:2552)
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3002)
... 46 more
Can anyone explain why this is happening?
Usuually this gives me the error message when trying to add a record, after i had the software running for more than about half a minute. seems to loose connection or something. when i run the program and quickly write a new record, it works
I was having the same sort of issue. I referred many post and comments but the thing worked for me was changing some parameters of the my.cnf file. Hope it will help you also ....
Set following parameters in my.cnf [mysqld] section
interactive_timeout=180 # "No.of sec. a server waits for activity on interactive connection before closing it"
wait_timeout=180 # "No. of sec. a server waits for an activity on a connection before closing it"
max_connect_errors=9999 # "More than this number of interrupted connections from a host this host will be blocked from further connections"
skip-name-resolve # "Don't resolved host names. All host names are IP's"
Sometimes this problem comes due to size of system RAM.May be you are inserting the data using buffer through RAM. To get out of this problem.
Set the Auto commit disable before inserting the data.
insert some amount of data appropriate to your System RAM (not the
whole).
Commit the query.
Do the steps 2 and 3 again until the whole insertion will not be
done.
You can understand this by the following code.
public static void main(string args[])
{
Connection con = null;
Statement stm = null;
int i;
float ratio;
ratio=1.0f;
try
{
Class.forName("com.mysql.jdbc.Driver");
// Connecting to the database
con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/demo",
"ashish", "impetus");
File f = new File("filler"); // taking the random text data from the file
// filler.txt and inserting that string
// in filler field of the relations
RandomAccessFile r = new RandomAccessFile(f,"r");
Random randomGenerator = new Random();
String strLine=new String();
int r1,flag=0;
stm = con.createStatement();
con.setAutoCommit(false) ;
int k=0;
i=0;
long sum2=0;
while(k%50000==0)
{
final long start = currentTimeMillis();
final StringBuilder builder =
new StringBuilder("INSERT INTO accounts
(aid, bid,abalance,filler) VALUES ");
while(i!=naccounts*ratio*scale )
{
int j=i+1;
for(int l=0;l<40;l++)
{
strLine+=((char)r.read());
r.skipBytes(0);
}
r1=randomGenerator.nextInt(1500);
if(strLine.equals(""))
{
flag=1;
}
if(flag!=1)
{
strLine=strLine.replaceAll("\\s","");
strLine=strLine.replaceAll("\\t","");
}
flag=0;
if (i%50000!=0)
{
builder.append(",");
}
builder.append(format("(%s, %s, %s, '%s')", j,
i/naccounts+1, 0, strLine));
strLine="";
r.seek(r1);
i++;
if(i%50000==0||i>=naccounts*ratio*scale)
{
final String query = builder.toString();
final PreparedStatement statement1 = con.prepareStatement(query);
statement1.execute();
con.commit();
final long stop= currentTimeMillis();
sum2=sum2+(stop-start);
statement1.close();
}
if(i%50000==0||i>=naccounts*ratio*scale)
{
break;
}
}
k=k+50000;
if(k>naccounts*ratio*scale)
{
break;
}
}
System.out.println(i+" rows inserted accounts table ");
System.out.println("time taken = "+sum2+" milliseconds");
}
catch (SQLException e)
{
System.out.println("Connection Failed! Check output console");
e.printStackTrace();
return;
}
catch (Exception e)
{
e.printStackTrace();
}
}
Did you follow/read this tutorial :
Connectivity with MYSQL
You have a part for your exception which can be useful for you.
I will quote something about your specific exception, just try that :
If you get a SQLException: Connection refused or Connection timed out
or a MySQL specific CommunicationsException: Communications link
failure, then it means that the DB isn't reachable at all. This can
have one or more of the following causes:
IP address or hostname in JDBC URL is wrong. Hostname in JDBC URL is
not recognized by local DNS server. Port number is missing or wrong in
JDBC URL. DB server is down. DB server doesn't accept TCP/IP
connections. DB server has run out of connections. Something in
between Java and DB is blocking connections, e.g. a firewall or proxy.
To solve the one or the other, follow the following advices:
Verify and test them with ping. Refresh DNS or use IP address in JDBC
URL instead. Verify it based on my.cnf of MySQL DB. Start the DB.
Verify if mysqld is started without the --skip-networking option.
Restart the DB and fix your code accordingly that it closes
connections in finally. Disable firewall and/or configure
firewall/proxy to allow/forward the port.

Categories

Resources