[kaffe] java.lang.ClassCastException

Jim White jim at pagesmiths.com
Fri Dec 15 23:38:08 PST 2006


Lam King Tin wrote:

> ...
> SingleByteCharsetConverter converter = (SingleByteCharsetConverter) 
> this.charsetConverterMap.get(javaEncodingName);
> 
> Do you know what's the reason of the casting exception and any manageable 
> solution? Thank you very much.
> 
> Best regards,
> King Tin
>  
> SQL Exception:  Unable to connect to any hosts due to exception: 
> java.lang.ClassCastException: can't cast `java/lang/Object' to 
> `com/mysql/jdbc/SingleByteCharsetConverter'
> 
> ** BEGIN NESTED EXCEPTION ** 
> 
> java.lang.ClassCastException
> MESSAGE: can't cast `java/lang/Object' to 
> `com/mysql/jdbc/SingleByteCharsetConverter'
> 
> STACKTRACE:
> 
> java.lang.ClassCastException: can't cast `java/lang/Object' to 
> `com/mysql/jdbc/SingleByteCharsetConverter'
>         at com.mysql.jdbc.Connection.getCharsetConverter(Connection.java:2046)

I don't know much about Kaffe, but the message makes clear that 
something odd has happened.  Someone has put a plain "java.lang.Object" 
into the converter map under the encoding you're trying to use.  It 
would seem to make a lot more sense that the encoding is missing than 
there would be an illegal object.

It would probably be helpful to know which character encoding you're using.

http://dev.mysql.com/downloads/connector/j/3.0.html

mysql-connector-java-3.0.17-ga/com/mysql/jdbc/Connection.java

Okay, I did a little (okay, a lot) more digging.  Here's the relevant 
source:

     /**
      * Marker for character set converter not being available (not written,
      * multibyte, etc)  Used to prevent multiple instantiation requests.
      */
     private final static Object CHARSET_CONVERTER_NOT_AVAILABLE_MARKER 
= new Object();

....

     synchronized SingleByteCharsetConverter getCharsetConverter(
         String javaEncodingName) {
         SingleByteCharsetConverter converter = 
(SingleByteCharsetConverter) this.charsetConverterMap
             .get(javaEncodingName);

         if (converter == CHARSET_CONVERTER_NOT_AVAILABLE_MARKER) {
             return null;
         }

         if (converter == null) {
             try {

So they intended to detect missing encoding sets, but the logic is 
broken (the cast will always throw an exception before the test can be 
made).  You could fix this code so that it returns null as intended on 
missing converters.  I looked in the source for that same file in 5.0, 
and the above bug is fixed.  Copy-and-pasting just that method might do 
the trick.

http://dev.mysql.com/downloads/connector/j/5.0.html

	/**
	 * Returns the locally mapped instance of a charset converter (to avoid
	 * overhead of static synchronization).
	 *
	 * @param javaEncodingName
	 *            the encoding name to retrieve
	 * @return a character converter, or null if one couldn't be mapped.
	 */
	SingleByteCharsetConverter getCharsetConverter(
			String javaEncodingName) throws SQLException {
		if (javaEncodingName == null) {
			return null;
		}

		if (this.usePlatformCharsetConverters) {
			return null; // we'll use Java's built-in routines for this
			             // they're finally fast enough
		}
		
		SingleByteCharsetConverter converter = null;
		
		synchronized (this.charsetConverterMap) {
			Object asObject = this.charsetConverterMap
			.get(javaEncodingName);

			if (asObject == CHARSET_CONVERTER_NOT_AVAILABLE_MARKER) {
				return null;
			}
			
			converter = (SingleByteCharsetConverter)asObject;
			
			if (converter == null) {
				try {
					converter = SingleByteCharsetConverter.getInstance(
							javaEncodingName, this);

					if (converter == null) {
						this.charsetConverterMap.put(javaEncodingName,
								CHARSET_CONVERTER_NOT_AVAILABLE_MARKER);
					} else {
						this.charsetConverterMap.put(javaEncodingName, converter);
					}
				} catch (UnsupportedEncodingException unsupEncEx) {
					this.charsetConverterMap.put(javaEncodingName,
							CHARSET_CONVERTER_NOT_AVAILABLE_MARKER);

					converter = null;
				}
			}
		}

		return converter;
	}



Also setting the character encoding to be one that is supported could 
help.  If you need an unsupported character encoding then it could be 
added to Kaffe (probably the most difficult option).

Jim





More information about the kaffe mailing list