[CONJ-104] Malformed communication exception if getMetaData before executeQuery Created: 2014-08-06  Updated: 2014-10-13  Resolved: 2014-10-10

Status: Closed
Project: MariaDB Connector/J
Component/s: None
Affects Version/s: 1.1.7
Fix Version/s: 1.1.8

Type: Bug Priority: Minor
Reporter: Fabien Morand Assignee: Massimo Siani (Inactive)
Resolution: Not a Bug Votes: 1
Labels: None
Environment:

Windows XP, MySQL, Java application, BIRT (report)


Attachments: Text File log_birt_maille_fine_maria.log     File mariadb-java-client-1.1.7.jar     Java Archive File mariadb-java-client-1.1.8-preview-sources.jar     Java Archive File mariadb-java-client-1.1.8-preview.jar    

 Description   

Problem was discovered while using BIRT, and can be reproduced with a simple java class.

If you create a PreparedStatement, and call getMetaData() method before executeQuery(), then you will get an error when executeQuery() is called.

Error is:
SQL error #1:Malformed communication packet.
(full log in file)

Quick fix:
In order to advance in our work, we have found a quick fix. We have commented the following instruction in MySQLPreparedStatement.getMetaData() method:
//ssps.close();

However this fix is probably not the best solution. If executeQuery() has not been called, then a new PreparedStatement has to be created in order to gather the metadata. This seems to be done by MySQLServerSidePreparedStatement, however something seems to go wrong when closed() is called.

Simple code to reproduce the problem:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class TestClass {

public static void main(String[] args) {
try

{ Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:..."); PreparedStatement ps = connection.prepareStatement("select ..."); ps.getMetaData(); ResultSet rs = ps.executeQuery(); ps.close(); connection.close(); }

catch(Exception e)

{ e.printStackTrace(); }

}
}



 Comments   
Comment by Fabien Morand [ 2014-08-08 ]

Here is a better fix proposal:

public ResultSetMetaData getMetaData() throws SQLException {
ResultSet rs = getResultSet();
ResultSetMetaData rsmd = null;
MySQLPreparedStatement ssps = null;
if (rs != null)

{ return rs.getMetaData(); }

try {
ssps = new MySQLPreparedStatement(connection, this.sql);
int paramCount = ssps.dQuery.getParamCount();

for (int i = 1; i <= paramCount; i++)

{ ssps.setString(i, ""); }

boolean hasResults = ssps.execute();

if(hasResults)

{ rs = ssps.getResultSet(); rsmd = rs.getMetaData(); }

else

{ rsmd = new MySQLResultSetMetaData(new MySQLColumnInformation[0], 0); }

} finally {
if(ssps != null)

{ ssps.close(); }

if(rs != null)

{ rs.close(); }

}

return rsmd;
}

Comment by Massimo Siani (Inactive) [ 2014-09-29 ]

Could you please check out https://code.launchpad.net/~massimo-siani/mariadb-java-client/CONJ-104 and tell why I don't get the same issue?

Comment by Fabien Morand [ 2014-10-08 ]

Can you provide an archive with the classes ? Bazaar is annoying me with certificate issue, and I don't have time to spend making it work. Thank you.

Comment by Massimo Siani (Inactive) [ 2014-10-08 ]

Attached.

Comment by Fabien Morand [ 2014-10-09 ]

Here is the jar that I use. I do have the problem, even with a very simple query. I will now try with your linked 1.1.8 jar.

java.sql.SQLException: Malformed communication packet.
at org.mariadb.jdbc.internal.SQLExceptionMapper.get(SQLExceptionMapper.java:149)
at org.mariadb.jdbc.internal.SQLExceptionMapper.throwException(SQLExceptionMapper.java:106)
at org.mariadb.jdbc.MySQLStatement.executeQueryEpilog(MySQLStatement.java:264)
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:288)
at org.mariadb.jdbc.MySQLStatement.executeQuery(MySQLStatement.java:302)
at org.mariadb.jdbc.MySQLPreparedStatement.executeQuery(MySQLPreparedStatement.java:112)
at test.Test.main(Test.java:16)
Caused by: org.mariadb.jdbc.internal.common.QueryException: Malformed communication packet.
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.getResult(MySQLProtocol.java:942)
at org.mariadb.jdbc.internal.mysql.MySQLProtocol.executeQuery(MySQLProtocol.java:991)
at org.mariadb.jdbc.MySQLStatement.execute(MySQLStatement.java:281)
... 3 more

Comment by Fabien Morand [ 2014-10-09 ]

I tried with the 1.1.8 preview jar and I still get the same error. If getMetadata is called before executeQuery, then I get the error.

Comment by Massimo Siani (Inactive) [ 2014-10-10 ]

I have been able to reproduce this bug with MySQL server only, not with MariaDB. MySQL is known to behave this way (not sure if http://bugs.mysql.com/bug.php?id=70664 is related in any way).

MariaDB server (5.5.40 and 10.0.14) does not suffer from the same bug. Do you have any chance to test it?

I tested with MySQL 5.6.21 on CentOS, the OS should be irrelevant.

Your workaround can work, but this is not a driver bug.

Comment by Fabien Morand [ 2014-10-13 ]

Thank you for your time, our target is MySQL so we will keep it this way.

Generated at Thu Feb 08 03:13:12 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.