Bug #16711 Connector/J requires LinkedHashMap
Submitted: 22 Jan 2006 19:01 Modified: 23 Jan 2006 3:56
Reporter: John Jacob Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:3.1.12 OS:Any (all)
Assigned to: CPU Architecture:Any

[22 Jan 2006 19:01] John Jacob
Description:
When trying to execute a query using JDK 1.3 (specifically, the JDK in WebSphere 4.0.7), I get the exception below.  The problem appears to be that NonRegisteringDriver on line 266 creates a new Connection, Connection contains several instances of LRUCache, LRUCache extends LinkedHashMap, and LinkedHashMap doesn't exist until JDK 1.4.  ConnectionProperties does check for the existence of LinkedHashMap and turns off metadata caching if it doesn't.  But Connection/LRUCache does not seem to do any such checks.

The documentation for 3.1.12 states:

"MySQL Connector/J supports Java-2 JVMs, including JDK-1.2.x, JDK-1.3.x, JDK-1.4.x and JDK-1.5.x, and requires JDK-1.4.x or newer to compile (but not run). MySQL Connector/J does not support JDK-1.1.x or JDK-1.0.x"

And the main Connector/J product page in the Interoperability section states that it works with "IBM WebSphere Application Server 4.0".

These statements are incorrect.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
java.lang.NoClassDefFoundError: java/util/LinkedHashMap
	at java.lang.ClassLoader.defineClass0(Native Method)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:703)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:133)
	at java.net.URLClassLoader.defineClass(URLClassLoader.java:319)
	at java.net.URLClassLoader.access$400(URLClassLoader.java:92)
	at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java:677)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:238)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:516)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:441)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:448)
	at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:266)
	at java.sql.DriverManager.getConnection(DriverManager.java:543)
	at java.sql.DriverManager.getConnection(DriverManager.java:163)

How to repeat:
Try to execute any query while using a JDK prior to 1.4.

Suggested fix:
Either:

1. Change the documentation to clearly state that Connector/J only works with JDK 1.4 and later.  (Obviously, this would be a big problem for anyone, such as myself, using JDK 1.3.  This is not recommended.)

2. When LinkedHashMap is not present, have Connection use a cache object that doesn't extend LinkedHashMap.

3. Provide your own implementation of LinkedHashMap that doesn't require JDK 1.4 or later.  (I think this is the best option.  This could also be used for metatdata caching.)
[23 Jan 2006 3:56] Mark Matthews
From the same paragraph in the manual:

"Because of the implementation of java.sql.Savepoint, Connector/J 3.1.0 and newer will not run on JDKs older than 1.4 unless the class verifier is turned off (-Xverify:none), as the class verifier will try to load the class definition for java.sql.Savepoint even though it is not accessed by the driver unless you actually use savepoint functionality. 

Caching functionality provided by Connector/J 3.1.0 or newer is also not available on JVMs older than 1.4.x, as it relies on java.util.LinkedHashMap which was first available in JDK-1.4.0. "

You need to use -Xverify:none with your JVM for WebSphere to avoid the class verifier trying to pull in classes that are listed in the driver, but never referenced.

JDK-1.3.x is reaches final end-of-life next month (and has been on life support for some time now), so we don't plan on making fixes that address compatibility issues with JDK-1.3.0, and haven't for some time. Since there's a work-around in this case, there is no plan to do gymnastics to avoid the class verifier or to implement our own linked hash map.