Bug #29636 Connector/J 5.0.6
Submitted: 9 Jul 2007 6:04 Modified: 31 Aug 2007 14:21
Reporter: Greger Haga Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:5.0.6 OS:Linux
Assigned to: CPU Architecture:Any
Tags: on linux fc6 with mysql-5.0.41-linux-i686

[9 Jul 2007 6:04] Greger Haga
Description:
[vokadoka@localhost bug]$ cat stacktrace.txt
SQL Exception:java.sql.SQLException: Error during query: Unexpected Exception: java.io.CharConversionException message given: null

Nested Stack Trace:

** BEGIN NESTED EXCEPTION **

java.io.CharConversionException

STACKTRACE:

java.io.CharConversionException
   at gnu.gcj.convert.Input_iconv.read(libgcj.so.7rh)
   at java.lang.String.init(libgcj.so.7rh)
   at java.lang.String.<init>(libgcj.so.7rh)
   at com.mysql.jdbc.SingleByteCharsetConverter.<init>(SingleByteCharsetConverter.java:153)
   at com.mysql.jdbc.SingleByteCharsetConverter.initCharset(SingleByteCharsetConverter.java:108)
   at com.mysql.jdbc.SingleByteCharsetConverter.getInstance(SingleByteCharsetConverter.java:86)
   at com.mysql.jdbc.Connection.getCharsetConverter(Connection.java:3477)
   at com.mysql.jdbc.StringUtils.getBytes(StringUtils.java:611)
   at com.mysql.jdbc.Buffer.writeStringNoNull(Buffer.java:655)
   at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1671)
   at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
   at com.mysql.jdbc.Connection.configureClientCharacterSet(Connection.java:2515)
   at com.mysql.jdbc.Connection.initializePropsFromServer(Connection.java:4111)
   at com.mysql.jdbc.Connection.createNewIO(Connection.java:2762)
   at com.mysql.jdbc.Connection.<init>(Connection.java:1553)
   at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
   at java.sql.DriverManager.getConnection(libgcj.so.7rh)
   at testconn.main(testconn.java:23)

** END NESTED EXCEPTION **

How to repeat:
clean installation, no configuration done, use Connector/J with this program:

import java.sql.Connection;
import java.sql.SQLException;
import com.mysql.jdbc.Driver;
import java.sql.DriverManager;
import java.util.Properties;
public class testconn
{
        public static void main(String[] argv)
        {
            try
            {
                Class.forName("com.mysql.jdbc.Driver");
                Driver d = new com.mysql.jdbc.Driver();
                if ( d == null )
                {
                    throw new NullPointerException("failed to get driver.");
                }
                String url = "jdbc:mysql://localhost/a_db";
                Connection conn = null;
                Properties p = new Properties();
                p.setProperty("user", "user");
                p.setProperty("password", "passwd");
                DriverManager.getConnection(url, p);
                if ( conn == null )
                {
                    throw new SQLException("connect failed.");
                }
                System.out.println("connection successful");
                conn.close();
            }
            catch(NullPointerException npe)
            {
                System.out.println(npe + npe.getCause().toString() );
                npe.printStackTrace();
            }
            catch(ClassNotFoundException e)
            {
                System.out.println(e);
            }
            catch(SQLException e)
            {
                System.out.println("SQL Exception:"+e.toString());
            }
            catch(Exception e1)
            {
                System.out.println("exception" + e1.toString() );
            }
        }
}
[9 Jul 2007 10:32] Sveta Smirnova
Thank you for the report.

I can not repeat described behaviour. Please indicate version of JDK you have.
[9 Jul 2007 14:28] Mark Matthews
It appears you're using GCJ which has a bug in its class libraries in that it throws an exception where no other VM (IBM, Sun, Blackdown, BEA). The other VMs return '?' for non-convertible character sequences.

If you can switch to another VM this problem goes away. Otherwise, please try adding "useJvmCharsetConverters=true" to your JDBC connection URL properties and see if that works, as that will cause the driver to use a different code path that doesn't cause the code in GCJ's class libraries with the bug to be executed.
[9 Jul 2007 15:05] Greger Haga
problem solved. 

due to missing default-character-set statement both for client and server in /etc/my.cnf the problem occured. 

Adding hte following:
default-character-set=utf8
both for [mysqld] as well as for client solved the problem. Still it should be checked as it would be nice to get somekind of info/warning when they are absent. 
thank you for prompt reply and your time.
[9 Jul 2007 15:17] Mark Matthews
No, that's not really the issue.

When you set the character set to "utf-8" on the MySQL server, then Connector/J detects that and uses it. Because UTF-8 is a multi-byte encoding, the driver doesn't use it's own single-byte character set conversion routines (which are more efficient than the ones in the class library), but also cause the issue with this bug with GCJ.

Effectively, you've done the same thing as telling the driver to use the built-in VM character set converters for _all_ character sets as I proposed earlier.

I'll alert the documentation team to put this in the FAQ related to GCJ.
[31 Aug 2007 14:21] MC Brown
An entry has been added to the C/J FAQ: 

When using gcj an java.io.CharConversionException is raised when working with certain character sequences.

This is a known issue with gcj which raises an exception when it reaches an unknown character or one it cannot convert. You should add useJvmCharsetConverters=true to your connection string to force character conversion outside of the gcj libraries, or try a different JDK.