Bug #57081 read_default_file not supported
Submitted: 28 Sep 2010 23:31 Modified: 11 Nov 2010 19:38
Reporter: Buck Golemon Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / J Severity:S4 (Feature request)
Version:5.1.13 OS:Any
Assigned to: CPU Architecture:Any

[28 Sep 2010 23:31] Buck Golemon
Description:
The following connection URL does not work in Connector/J, although it should.
   jdbc:mysql:///?read_default_file=/etc/mysql-config/app3.cnf

Works in Python:
    from MySQLdb import connect
    connect( read_default_file='/etc/mysql-config/app3.cnf' )

Works in Perl:
    use DBI;
    DBI->connect("DBI:mysql:;mysql_read_default_file=/etc/mysql-config/app3.cnf");

How to repeat:
create a file such as:

/home/me/my.conf:

[client]
    user	= me
    password	= nopass
    database    = test
    host	= myhost.acme.com
    port	= 12345

and try to connect to this database with Connector/J using this URL:
    jdbc:mysql:///?read_default_file=/home/me/my.cnf

Instead of using the file values, the default values will be used, resulting in a "Connection refused" error.

Suggested fix:
Enhance com.mysql.jdbc.NonRegisteringDriver.parseURL to understand 'read_default_file' (and 'read_default_group') and fill in properties accordingly.
[28 Sep 2010 23:44] Mark Matthews
In general, file access from J(2)EE infrastructure components such as JDBC drivers is highly discouraged by the JDBC and JEE specifications themselves. 

The driver doesn't use libmysql either, so it doesn't understand 99% of the items that may be in a my.cnf style file, therefore there is not much chance this will be implemented. Is there a reason you're not doing this in a more java-friendly way, i.e. in your data source config?
[28 Sep 2010 23:49] Mark Matthews
(we may reconsider the feasibility of this if we understand your use case better, but in general reading proprietary config files is not the "java way" of configuring infrastructure components that are part of the "core" J2SE and JEE specifications)
[29 Sep 2010 0:32] Buck Golemon
We'd like to enable changing this one file and have all the relevant applications follow along.

Only understanding 1% of the values in the config is fine (host, port, db, user, passwd).
Read-only file accesses are also not ok? Even when the user requests it?

As background, we're using the connector via a third-party app (pentaho kettle), so there is no way to parse the file myself.
[29 Sep 2010 0:55] Mark Matthews
*Technically* file access isn't allowed, generally it's not encouraged, because one doesn't know that your code is running on the same physical host at any one time.

Practically, one can access files, but it's not guaranteed to work.

You could do what you want today by implementing com.mysql.jdbc.ConnectionPropertiesTransform and converting these properties when reading the file:

public interface ConnectionPropertiesTransform {
	/**
	 * The JDBC driver will call this method if the user has loaded your
	 * implementation of this interface by specifying the 'propertiesTransform'
	 * property in their JDBC URL.
	 * 
	 * @param props
	 *            the properties as passed by the driver (never null)
	 * 
	 * @return the same properties with any transformations that your
	 *         implementation has made
	 * 
	 * @throws SQLException
	 *             if a transform can not be made for any reason.
	 */
	public Properties transformProperties(Properties props) throws SQLException;
[29 Sep 2010 1:16] Buck Golemon
I'm not a Java guy, so it will take me a full week to understand what you mean, implement it, and get it working under kettle. 

Not that I expect a new release of Connector/J sooner than that :), but it's not a good use of our time budget.

I understand that the external my.cnf is not the 'java way', but it's also not The Way in Perl/Python/C, but it's supported for added manageability, convenience, and security.

manageability:
    central config file can be used by multiple applications in various languages.

convenience:
    one property instsead of five. less typos.

security:
    read-protect the file and the code is only runnable by certain people.

Thanks for considering,
--Buck
[11 Nov 2010 19:38] Buck Golemon
I've changed this to S4 (Feature request).

You indicated that you would like to understand our use case better.

We have ~10 mysqld instances in production and a test instance for each. In addition, each developer has a private test server for whichever app they happen to be working on. We handle this complexity by leveraging my.cnf files. The production and central test connection information is version-controlled in a central area. 

All of our systems reference these files directly when connecting to a server, and so developers are motivated to keep these up-to-date with all changes. Most commonly we edit the files to accommodate a change of server due to hardware failure or resource shortage. Our systems continue to "just work" because they reference these external config files, and no edits to scripts are needed.

This supported at the connector level for all of our major languages (perl, python, shell, even C), but is not supported by Connector/J, which led me to file this ticket. If we look at those other connectors they also "don't understand 99% of the items that may be in a my.cnf style file." Only the directives that may appear in the [client] section are required, which I believe is only ~8 items.

Regards,
--Buck

PS: Can we set this to "Open" or something other than "Not a Bug"?