Bug #47494 Port in JDBC Connection String is ignored by DriverManager.getConnection()
Submitted: 21 Sep 2009 19:07 Modified: 1 Oct 2009 9:45
Reporter: Jens Nehlmeier Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:5.1.9 OS:Any
Assigned to: Mark Matthews CPU Architecture:Any
Triage: D1 (Critical)

[21 Sep 2009 19:07] Jens Nehlmeier
Description:
The DriverManager.getConnection() methods do not use the specified non-standard port on the jdbc connection string (e.g. jdbc:mysql://localhost:6777). The JDBC driver always uses standard port 3306 for connection creation.

When using an older Connector/J (e.g. 5.1.5) it works like expected.

The bug is may be related to http://bugs.mysql.com/bug.php?id=32216 . It seems that parseURL() has been corrected but getConnection() has not been updated to use the PORT (PORT.n) key of the connection properties map.

For the connection string "jdbc:mysql://localhost:6777" Connector/J 5.1.9 creates the properties map

{HOST=localhost, HOST.1=localhost, PORT=6777, NUM_HOSTS=1, PORT.1=6777}

and trys to connect to localhost:3306 whereas Connector/J 5.1.5 will create

{HOST=localhost:6777}

and trys to connect to localhost:6777.

How to repeat:
- Start MySQL server on default port 3306.
- Execute the Java application below with Connector/J 5.1.9 as JDBC library.
- The application will successfully establish a connection to MySQL server running on localhost:3306 although localhost:6777 has been specified.
- Change JDBC library from Connector/J 5.1.9 to (e.g.) Connector/J 5.1.5 and the application will throw a com.mysql.jdbc.exceptions.jdbc4.CommunicationsException because it now trys to connect to localhost:6777 where no MySQL server is running.

Java application:
------------

package jdbctest;

import com.mysql.jdbc.Driver;
import java.sql.DriverManager;
import java.util.Properties;

public class Main {

    public static void main(String[] args) throws Exception {

        String url = "jdbc:mysql://localhost:6777";        
        
        Driver driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();

        Properties result = driver.parseURL(url, new Properties());
        System.out.println(result);

        DriverManager.getConnection(url, result);

    }

}
[22 Sep 2009 6:38] Tonci Grgin
Hi Jens and thanks for your report.

If I understand correctly, your complaint is in that c/J will fall back to default port if no MySQL server is to be found on given port, right?
If so, I'd like to think it's a feature, undocumented maybe, rather than a bug.
[22 Sep 2009 8:21] Jens Nehlmeier
Hi,

no I do not mean that c/J 5.1.9 does fall back to default port if no MySQL server is running on the specified port. c/J just does not use the specified port even if a server is running on that port.

You can also do the following:
- Start MySQL on port 6777
- Specify a connection string "jdbc:mysql://localhost:6777"
- c/J 5.1.5 will connect to port 6777 whereas c/J 5.1.9 throws an exception because it trys to connect to default port 3306 where no server is running. 

=> c/J 5.1.9 ignores port 6777 on the connection string.
[22 Sep 2009 9:03] Tonci Grgin
Verified as described.

.Loading JDBC driver 'com.mysql.jdbc.Driver'
Done.

com.mysql.jdbc.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
[22 Sep 2009 9:08] Tonci Grgin
Changing triage.
[22 Sep 2009 9:57] Eric Herman
I notice that on line 344 of com.mysql.jdbc.ConnectionImpl

protected static Connection getInstance(String hostToConnectTo,
			int portToConnectTo, Properties info, String databaseToConnectTo,
			String url) throws SQLException

that we *are* in fact getting the correct port, so it's not a parsing of the url issue:

hostToConnectTo: localhost
portToConnectTo: 6777
databaseToConnectTo: null
url: jdbc:mysql://localhost:6777
info: {HOST=localhost, HOST.1=localhost, PORT=6777, NUM_HOSTS=1, PORT.1=6777}

Will look deeper.
[22 Sep 2009 10:29] Eric Herman
patch for BUG#47494 which adds the portToConnectTo when adding a host to the hostList

Attachment: connector-j-5-1-BUG_47494-add_port_to_hostList-1.diff (application/octet-stream, text), 680 bytes.

[22 Sep 2009 13:58] Mark Matthews
Fixed for 5.1.10
[1 Oct 2009 9:45] Tony Bedford
An entry has been added to the 5.1.10 changelog:

The DriverManager.getConnection() method ignored a non-standard port if it was specified in the JDBC connection string. Connector/J always used the standard port 3306 for connection creation. For example, if the string was jdbc:mysql://localhost:6777, Connector/J would attempt to connect to port 3306, rather than 6777.