DBCP Connection Problem with Sun One Application Server 7.0

Hi

I'm using DBCP for connection pooling in my application. I have developed the application using Tomcat 5.0 and DBCP seem to work fine under tomcat context, the production server is Sun One application server, and the database is MS Sql server 2000 (with window authentication). My code seem to work fine on Tomcat-SQLServer combination (with/without windows authentication mode) but it does not work under Sun One Application server. Is there any assumption of DBCP library that its running under Apache's tomcat's environment?

Error:

[24/May/2006:11:15:47] WARNING ( 924):CORE3283: stderr: java.sql.SQLException: [Microsoft][ODBC SQL Server Driver][SQL Server]Login failedfor user'MYDOMAIN\BC334113$'.

24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6958)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:7115)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sun.jdbc.odbc.JdbcOdbc.SQLDriverConnect(JdbcOdbc.java:3074)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sun.jdbc.odbc.JdbcOdbcConnection.initialize(JdbcOdbcConnection.java:323)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sun.jdbc.odbc.JdbcOdbcDriver.connect(JdbcOdbcDriver.java:174)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at java.sql.DriverManager.getConnection(DriverManager.java:512)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at java.sql.DriverManager.getConnection(DriverManager.java:171)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sa.com.aramco.ms.pams.development.objects.DevelopmentProvider.openDBConnection(DevelopmentProvider.java:43)

[24/May/2006:11:15:47] WARNING ( 924): CORE3283: stderr: at sa.com.aramco.ms.pams.development.objects.DevelopmentManager.getBuyerByLogon(DevelopmentManager.java:1667)

Even though it looks as though the error is with SQL server connection but I can run the exact same WAR file with no error on Tomcat 5.0.

Has anyone tried DBCP connection pooling with Sun One

[2254 byte] By [Ali-Iqbal] at [2007-11-26 7:32:12]
# 1

Please note that I'm manually configuring the DBCP connection pooling and I have tested it in a stand alone application, hence i believe there is some configuration Sun One Application Server requires before allowing conections to a database. I am not using Jndi hence i believe i do not need any connection pool or jdbc jndi resource registered.

AliIqbal at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 2
Hi,The exception seems to have come because of authentication failure"Login failed for user 'MYDOMAIN\BC334113$"Further, I could not see any DataSource (dbcp datasource) used to get the connectionin the code posted.Thanks,-Jagadish
JagadishPrasath at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 3
Hi,Can you provide the code snippet that you have used for getting DB connection? What is application server version that you using currently?Can you also provide the config settings that you modified at server?Thanks,-Balaji.
BalajiKoutharapu at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 4

Given below is the code that setup the driver, my class automatically maps standard ConnectionString to Apache DBCP connection string and sets up the driver on the fly, code is a bit long to be pasted completed right here... please note my connection does not depend upon any jndi resource, it needs to open connection to the database using manually setup Dbcp connection pool. The get connection call works with Tomcat however it doesn't work with SunOne Application server.

I'm using Sun One Application Server 7.

private void loadDriver(String driverName)

{

Logger logger = DbcpConnectionConfiguration.getLogger();

try

{

if( !loadedDriverList.contains( driverName ) )

{

Class.forName(driverName).newInstance();

loadedDriverList.add( driverName );

}

}

catch( ClassNotFoundException ce )

{

logger.error("In Loading Provider driver class"+driverName+". Error:"+ce.getMessage());

System.out.println("In Loading Provider driver class"+driverName+". Error:"+ce.getMessage());

}

catch( InstantiationException e )

{

logger.error("Error Initializing Driver class"+driverName+". Error:"+e.getMessage());

System.out.println("Error Initializing Driver"+driverName+". Error:"+e.getMessage());

}

catch (IllegalAccessException e)

{

logger.error("Error Initializing Driver"+driverName+"Error:"+e.getMessage());

System.out.println("Error Initializing Driver"+driverName+"Error:"+e.getMessage());

}

}

public void setupDriver(String connectURI, String userId, String password) throws Exception

{

//

// First, we'll need a ObjectPool that serves as the

// actual pool of connections.

//

// We'll use a GenericObjectPool instance, although

// any ObjectPool implementation will suffice.

//

GenericObjectPool genericPool = new GenericObjectPool(null);

//configure the pool from the configuration file.

configurePool( genericPool );

ObjectPool connectionPool = genericPool;

//

// Next, we'll create a ConnectionFactory that the

// pool will use to create Connections.

// We'll use the DriverManagerConnectionFactory,

// using the connect string passed in the command line

// arguments.

//

ConnectionFactory connectionFactory = null;

if( userId.length() > 0 )

connectionFactory = new DriverManagerConnectionFactory(connectURI,userId, password);

else

connectionFactory = new DriverManagerConnectionFactory(connectURI,null);

//

// Now we'll create the PoolableConnectionFactory, which wraps

// the "real" Connections created by the ConnectionFactory with

// the classes that implement the pooling functionality.

//

PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true);

//

// Finally, we create the PoolingDriver itself...

//

Class.forName("org.apache.commons.dbcp.PoolingDriver");

PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");

String connectionIdentifier = getConnectionIdentifier(connectURI);

//

// ...and register our pool with it.

//

driver.registerPool(connectionIdentifier,connectionPool);

//adding the pooled connection into the pooled connection list.

pooledConnectionList.add(connectURI);

//

// Now we can just use the connect string "jdbc:apache:commons:dbcp:example"

// to access our pool of Connections.

//

}

/* (non-Javadoc)

* @see sa.com.futureware.fastwork.fastdbconnectionmanagement.interfaces.IDbConnectionProvider#getConnection(java.lang.String, java.lang.String, java.lang.String, java.lang.String)

*/

public Connection getConnection(String driver, String url, String userName, String password) throws DbConnectionException

{

try

{

if( !pooledConnectionList.contains(url) )

{

if( !loadedDriverList.contains(driver) )

loadDriver( driver );

try

{

setupDriver( url, userName, password );

}

catch(Exception exception)

{

throw new DbConnectionException("Could load setup DBCP driver for the given url : "+url+". Error:"+exception.getMessage() );

}

}

String connectionIdentifier = getConnectionIdentifier( url );

if( connectionIdentifier.length() <= 0 )

throw new DbConnectionException("Could not create identifier for the connection url:"+url);

Connection con = DriverManager.getConnection(APACHE_DBCP_CONNECTION_URL+connectionIdentifier);

return con;

}

catch(SQLException sqlException )

{

throw new DbConnectionException("Could not create connection to "+url+". Error:"+sqlException.getMessage());

}

}

/**

* Configures the pool according to the set configuration.

* @param genericPool The pool to be configured.

*/

private void configurePool(GenericObjectPool genericPool)

{

// TODO Auto-generated method stub

DbcpConnectionConfiguration configuration = DbcpConnectionConfiguration.getConfiguration();

genericPool.setMaxActive(configuration.getMaxActive());

genericPool.setMaxIdle( configuration.getMaxIdle() );

genericPool.setMaxWait( configuration.getMaxWait() );

genericPool.setMinEvictableIdleTimeMillis( configuration.getMinEvictableIdleTimeMillis() );

genericPool.setTestOnBorrow( configuration.isTestOnBorrow() );

genericPool.setTestOnReturn( configuration.isTestOnReturn() );

genericPool.setTestWhileIdle( configuration.isTestWhileIdle() );

genericPool.setWhenExhaustedAction( configuration.getWhenExhaustedAction() );

genericPool.setTimeBetweenEvictionRunsMillis( configuration.getTimeBetweenEvictionRunsMillis() );

}

/**

* Gets a mapped Connection identifier. It only works with DSN based connection right now. returns the name of the DSN which acts as Dbcp connection pool name later.

* @param url

* @return

*/

private String getConnectionIdentifier(String url)

{

String connectionIdentifier = url.substring( url.lastIndexOf(':') + 1 );

return connectionIdentifier;

}

My Configuration File

<object class="sa.com.futureware.fastwork.dbcpconnectionprovider.DbcpConnectionConfiguration">

<!-- **** DBCP Connection Provider configuration **** -->

<void property="driverClassName">

<string>sun.jdbc.odbc.JdbcOdbcDriver</string>

</void>

<void property="connectionUrl">

<!--string>jdbc:microsoft:sqlserver://OFFICEWARE10:1433</string-->

<string>jdbc:odbc:SQLServerDB</string>

</void>

<!-- You can pass empty string if you are not using default jdbc connection provider -->

<void property="userName">

<string>PAMS</string>

</void>

<!-- You can pass empty string if you are not using default jdbc connection provider -->

<void property="password">

<string>purc</string>

</void>

<!-- Following is the Dbcp GenericObjectPool class configuration -->

<!-- please visit the following url for more details of these configuration paramters-->

<!-- http://jakarta.apache.org/commons/pool/apidocs/org/apache/commons/pool/impl/GenericObjectPool.html -->

<void property="maxActive">

<int>20</int>

</void>

<void property="maxIdle">

<int>10</int>

</void>

<void property="maxWait">

<long>2160000</long>

</void>

<void property="whenExhaustedAction">

<byte>1</byte>

</void>

<void property="testOnBorrow">

<boolean>false</boolean>

</void>

<void property="testOnReturn">

<boolean>false</boolean>

</void>

<void property="timeBetweenEvictionRunsMillis">

<long>2160000</long>

</void>

<void property="minEvictableIdleTimeMillis">

<long>36000</long>

</void>

<void property="testWhileIdle">

<boolean>false</boolean>

</void>

</object>

AliIqbal at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 5

Here is the stack trace of the error.

WARNING: CORE3283: stderr: java.sql.SQLException: Could not get Connection from

the database:ErrorCould not create connection to jdbc:odbc:SQLServerDB. Pool Nam

e:SQLServerDB. Error:[Microsoft][ODBC SQL Server Driver][SQL Server]Login failed

for user 'ARAMCO\BC364305$'.

WARNING: CORE3283: stderr:at sa.com.aramco.mso.pams.utilities.RDBProvider.

getConnection(RDBProvider.java:132)

WARNING: CORE3283: stderr:at sa.com.aramco.ms.pams.development.objects.Dev

elopmentProvider.openConnection(DevelopmentProvider.java:54)

WARNING: CORE3283: stderr:at sa.com.aramco.ms.pams.development.objects.Dev

elopmentManager.getBuyerByLogon(DevelopmentManager.java:1695)

WARNING: CORE3283: stderr:at sa.com.aramco.mso.pams.ui.usermanagement.Auth

enticator.authenticate(Authenticator.java:60)

WARNING: CORE3283: stderr:at sun.reflect.NativeMethodAccessorImpl.invoke0(

Native Method)

WARNING: CORE3283: stderr:at sun.reflect.NativeMethodAccessorImpl.invoke(N

ativeMethodAccessorImpl.java:39)

WARNING: CORE3283: stderr:at sun.reflect.DelegatingMethodAccessorImpl.invo

ke(DelegatingMethodAccessorImpl.java:25)

WARNING: CORE3283: stderr:at java.lang.reflect.Method.invoke(Method.java:3

24)

WARNING: CORE3283: stderr:at com.sun.faces.el.MethodBindingImpl.invoke(Met

hodBindingImpl.java:146)

WARNING: CORE3283: stderr:at com.sun.faces.application.ActionListenerImpl.

processAction(ActionListenerImpl.java:92)

WARNING: CORE3283: stderr:at javax.faces.component.UICommand.broadcast(UIC

ommand.java:332)

WARNING: CORE3283: stderr:at javax.faces.component.UIViewRoot.broadcastEve

nts(UIViewRoot.java:287)

WARNING: CORE3283: stderr:at javax.faces.component.UIViewRoot.processAppli

cation(UIViewRoot.java:401)

WARNING: CORE3283: stderr:at com.sun.faces.lifecycle.InvokeApplicationPhas

e.execute(InvokeApplicationPhase.java:95)

WARNING: CORE3283: stderr:at com.sun.faces.lifecycle.LifecycleImpl.phase(L

ifecycleImpl.java:245)

WARNING: CORE3283: stderr:at com.sun.faces.lifecycle.LifecycleImpl.execute

(LifecycleImpl.java:110)

WARNING: CORE3283: stderr:at javax.faces.webapp.FacesServlet.service(Faces

Servlet.java:213)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardWrapperValve

.invokeServletService(StandardWrapperValve.java:720)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardWrapperValve

.access$000(StandardWrapperValve.java:118)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardWrapperValve

$1.run(StandardWrapperValve.java:278)

WARNING: CORE3283: stderr:at java.security.AccessController.doPrivileged(N

ative Method)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardWrapperValve

.invoke(StandardWrapperValve.java:274)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardPipeline.inv

oke(StandardPipeline.java:505)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardContextValve

.invoke(StandardContextValve.java:212)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardPipeline.inv

oke(StandardPipeline.java:505)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardHostValve.in

voke(StandardHostValve.java:203)

WARNING: CORE3283: stderr:at org.apache.catalina.core.StandardPipeline.inv

oke(StandardPipeline.java:505)

WARNING: CORE3283: stderr:at com.iplanet.ias.web.connector.nsapi.NSAPIProc

essor.process(NSAPIProcessor.java:153)

WARNING: CORE3283: stderr:at com.iplanet.ias.web.WebContainer.service(WebC

ontainer.java:597)

AliIqbal at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 6

I'm not sure if I can solve your problem, but I several items that warrant further investigation:

1) the username that shows up in your stack trace is *not* the same username that is in your XML file -- with the JDBC/ODBC driver I believe you can either specify username/password information in the ODBC control panel or in the JDBC Connection. I'm not sure which takes precedence. Are you sure the wrong username isn't configured in the ODBC control panel?

2) this looks like it is doing a lot of work that would be better handled by the AppServer's JDBC connection pool and JNDI registry. It appears that the guts of your RDBProvider.getConnection or DevelopmentProvider.openConnection method could be pretty easily replaced by calls to look up the JNDI DataSource and return its Connection. Unless you have a need to dynamically connect to lots of different databases, I think it's a better/more supported way to go. It's also a supported method on modern versions of Tomcat (4.x+) which come with a JNDI-based DataSource (hiding the details of DBCP). That way, your code only depends on standard JDK classes (DataSource, Connection, Context) rather than the bowels of DBCP.

3) finally, just a warning the that JDBC/ODBC driver has plenty of issues and would not be a good solution for a production site. Either the Microsoft "thin" JDBC driver or the free "jTDS" drivers for SQL Server are good and production-ready.

HTH,

-=- D. J.

djhagberg at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...
# 7

The ID password in the ODBC connection does not matter when you are using SQL server windows authentication mode. And i have tried the code with 0 length string as well as null for user name and password but none of the things are working. Whereas under tomcat or any standalone application it is not considering the username and password altogether (which is correct and working).

My Connection pooling component code is suppose to be independent of the Application server, as it may run under a container and it may run as a standalone application hence i need not to depend upon the container provide JNDI connections. However, i can modify the code for this application as i know it is running under the container context.

JDBC driver option is for development purposes, we may not use the same driver for the production, and if you notice the code we have not hardcode the driver, hence we only need to change configuration and it will start loading the new driver.

The same code is working under tomcat this is the most strange part. We are using Windows authentication mode of MS SQL Server which might be the reason for this incompatibility. Has anyone tried ( Windows Authentication Sql Server + Sun One Application server )combination.

Mirza_92 at 2007-7-6 19:27:48 > top of Java-index,Application & Integration Servers,Application Servers...