Commons Dbcp
  1. Commons Dbcp
  2. DBCP-209

Is DataSource.getConnection(user, pass) working the way it is suppose to?

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 1.2.1
    • Fix Version/s: 1.3
    • Labels:
      None

      Description

      In Tomcat's server.xml, I create a DataSource resource using the FACTORY org.apache.commons.dbcp.BasicDataSourceFactory and I also provide a URL and a DRIVERCLASSNAME. However I do not provide USERNAME or PASSWORD because I want to use DataSource.getConnection(user, pass) in my application. When I call DataSource.getConnection(user, pass) I get the following exception, java.sql.SQLException: invalid arguments in call, which was unexpected. I dug into the source code for BasicDataSource and I found what I think is the source of the problem. First, the method getConnection(user, pass) call the createDataSource() method. The createDataSource() method creates a Properties object and tries to put the username and password into the properties object. However, because the server.xml file does contain a username or password, this Properties object (named connectionProperties in the code) is empty. The createDataSource() the proceeds to call the validateConnectionFactory() method. This method then tries to get a Connection object!! This attempt fails because the Properties object has no username or password in it hence the Oracle driver complains about being passed invalid arguments. My question is why is the code working this way? Why does the createDataSource() and validateConnectionFactory() methods assume the username and password have been set in server.xml and then attempt to try to return a Connection object with the username and password passed to the getConnection(user, pass) method? It would seem to me the createDataSource() and validateConnectionFactory() methods should be aware of the username and password passed to the getConnection(user, pass) if this method is used.

        Activity

        Hide
        Phil Steitz added a comment -

        I agree with Dain. For BasicDataSource, the username and password are pool properties.

        Show
        Phil Steitz added a comment - I agree with Dain. For BasicDataSource, the username and password are pool properties.
        Hide
        Dain Sundstrom added a comment -

        I believe that Michael should be using either the SharedPoolDataSource or the PerUserPoolDataSource which support the getConnection(user, pass) method. This pool keeps track of connection credentials, so when a connection is created, it can locate a connection authorized for the specified user.

        I think this issue should be closed as invalid.

        Show
        Dain Sundstrom added a comment - I believe that Michael should be using either the SharedPoolDataSource or the PerUserPoolDataSource which support the getConnection(user, pass) method. This pool keeps track of connection credentials, so when a connection is created, it can locate a connection authorized for the specified user. I think this issue should be closed as invalid.
        Hide
        Phil Steitz added a comment -

        Yes, that makes sense, but the way to do it is to have the application set properties on the pool - using setUsername, setPassword, instead of trying to do it per connection using getConnection(user, pass).

        Show
        Phil Steitz added a comment - Yes, that makes sense, but the way to do it is to have the application set properties on the pool - using setUsername, setPassword, instead of trying to do it per connection using getConnection(user, pass).
        Hide
        Michael Remijan added a comment -

        This make sense, but what about considering this. In Tomcat a datasource is configured with something like this:

        <Resource
        name="jdbc/TestDB"
        auth="Container"
        type="javax.sql.DataSource"
        />

        Now "auth" can have the values Container or Application. According to the Tomcat documentation if auth="Container" then Tomcat will take care of handling logging in. In this case the username and password of <ResourceParams /> makes sense. But if auth="Application" then the application is suppose to handle login. So I interpret this as using the getConnection(username, password) method. This make any sense?

        Show
        Michael Remijan added a comment - This make sense, but what about considering this. In Tomcat a datasource is configured with something like this: <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" /> Now "auth" can have the values Container or Application. According to the Tomcat documentation if auth="Container" then Tomcat will take care of handling logging in. In this case the username and password of <ResourceParams /> makes sense. But if auth="Application" then the application is suppose to handle login. So I interpret this as using the getConnection(username, password) method. This make any sense?
        Hide
        Phil Steitz added a comment -

        The problem with getConnection(user, pass) is that this call makes it look like authentication is happening at connection retrieval time and the actual parameters are properties of the connection. DBCP's BasicDataSource provides connections from a connection pool and the username and password properties are properties of the pool - i.e., all connections returned by this datasource share these properties, along with the URL and other connection properties. Authentication happens when the pool invokes the underlying connection factory's makeObject method, not when connections are retrieved by BasicDataSource clients.

        The current code (in RC now for 1.2.2) throws an UnsupportedOperationException when getConnection is invoked with username and password specified, which is less confusing to the client.

        If you want to delay specification of the username and password for the pool until the first connection retrieval, you can do this by using the setPassword and setUsername properties before the first connection retrieval is attempted.

        I am leaving this open, since if what you want is to have getConnection(user, pass) have the effect of setting these properties on the pool (closing and reinitializing if the pool has been initialized and the actual parameters are different from current values), we can talk about implementing that. Personally, I think it is best to force use of pool properties as above to handle this, though.

        Show
        Phil Steitz added a comment - The problem with getConnection(user, pass) is that this call makes it look like authentication is happening at connection retrieval time and the actual parameters are properties of the connection. DBCP's BasicDataSource provides connections from a connection pool and the username and password properties are properties of the pool - i.e., all connections returned by this datasource share these properties, along with the URL and other connection properties. Authentication happens when the pool invokes the underlying connection factory's makeObject method, not when connections are retrieved by BasicDataSource clients. The current code (in RC now for 1.2.2) throws an UnsupportedOperationException when getConnection is invoked with username and password specified, which is less confusing to the client. If you want to delay specification of the username and password for the pool until the first connection retrieval, you can do this by using the setPassword and setUsername properties before the first connection retrieval is attempted. I am leaving this open, since if what you want is to have getConnection(user, pass) have the effect of setting these properties on the pool (closing and reinitializing if the pool has been initialized and the actual parameters are different from current values), we can talk about implementing that. Personally, I think it is best to force use of pool properties as above to handle this, though.

          People

          • Assignee:
            Unassigned
            Reporter:
            Michael Remijan
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development