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
Category:Connector/J Severity:S2 (Serious)
Version:5.1.9 OS:Any
Assigned to: Mark Matthews Target Version:
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.