views:

632

answers:

4

I have the following code:

        Hashtable env1 = new Hashtable();

        env1.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY,"com.ibm.websphere.naming.WsnInitialContextFactory");
        log.info("Executed step 1");
        env1.put(javax.naming.Context.PROVIDER_URL, "iiop://myhost.com:9301");
        log.info("Executed step 2");    

        Context ctx = new InitialContext(env1);

        DataSource ds = (DataSource)ctx.lookup("jdbc/mydatasource");
        log.info("Excecuted lookup  ="+ds);

        conn = ds.getConnection();

I have the previous code in an standalone application that is connecting to WAS 6.1.0.3 in order to retrieve a connection from the datasource. The code is very straighforward, and I have seen the same code working in a different environment, but in this case when I call getConnection I get an exception. The datasource is WAS has the proper authentication alias set and when the connection is tested it works OK from the WAS side, but the previous code won't work.

If I change this line: conn = ds.getConnection();

to this: conn = ds.getConnection("username","password");

Then the code will work! But that's not what I want since the connections in the datasource should already have the credentials set. I was initially thinking this was a Sybase problem, but it's also happening with Oracle, so would rather say I have a problem with WAS.

If you are curious about the exceptions, for Sybase I get:

java.sql.SQLException: JZ004: User name property missing in DriverManager.getConnection(..., Properties).DSRA0010E: SQL State = JZ004, Error Code = 0
    at com.sybase.jdbc2.jdbc.ErrorMessage.raiseError(ErrorMessage.java:569)
    at com.sybase.jdbc2.tds.LoginToken.<init>(LoginToken.java:128)
    at com.sybase.jdbc2.tds.Tds.doLogin(Tds.java:506)
    at com.sybase.jdbc2.tds.Tds.login(Tds.java:449)
    at com.sybase.jdbc2.jdbc.SybConnection.tryLogin(SybConnection.java:254)
    at com.sybase.jdbc2.jdbc.SybConnection.regularConnect(SybConnection.java:230)
    at com.sybase.jdbc2.jdbc.SybConnection.<init>(SybConnection.java:200)
    at com.sybase.jdbc2.jdbc.SybPooledConnection.<init>(SybPooledConnection.java:72)
    at com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource.createConnection(SybConnectionPoolDataSource.java:138)
    at com.sybase.jdbc2.jdbc.SybDriver.connect(SybDriver.java:485)
    at com.sybase.jdbc2.jdbc.SybDriver.connect(SybDriver.java:517)
    at com.sybase.jdbc2.jdbc.SybDataSource.getConnection(SybDataSource.java:227)
    at com.sybase.jdbc2.jdbc.SybConnectionPoolDataSource.getPooledConnection(SybConnectionPoolDataSource.java:74)
    at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:897)
    at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
    at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:892)
    at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:1181)
    at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1047)
    at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:431)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:400)

And for Oracle I get this one:

java.sql.SQLException: invalid arguments in callDSRA0010E: SQL State = null, Error Code = 17,433
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:112)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:146)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:208)
    at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:236)
    at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:420)
    at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165)
    at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35)
    at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801)
    at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:297)
    at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:221)
    at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPhysicalConnection(OracleConnectionPoolDataSource.java:157)
    at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:94)
    at oracle.jdbc.pool.OracleConnectionPoolDataSource.getPooledConnection(OracleConnectionPoolDataSource.java:75)
    at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper$1.run(InternalGenericDataStoreHelper.java:897)
    at com.ibm.ws.security.util.AccessController.doPrivileged(AccessController.java:118)
    at com.ibm.ws.rsadapter.spi.InternalGenericDataStoreHelper.getPooledConnection(InternalGenericDataStoreHelper.java:892)
    at com.ibm.ws.rsadapter.spi.WSRdbDataSource.getPooledConnection(WSRdbDataSource.java:1181)
    at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.createManagedConnection(WSManagedConnectionFactoryImpl.java:1047)
    at com.ibm.ws.rsadapter.spi.WSDefaultConnectionManagerImpl.allocateConnection(WSDefaultConnectionManagerImpl.java:81)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:431)
    at com.ibm.ws.rsadapter.jdbc.WSJdbcDataSource.getConnection(WSJdbcDataSource.java:400)

In both cases I won't the exception if I pass the credentials to the getConnection method

Thanks for your advice.

A: 

It's been a long time since I've done anything with WebSFEAR^H^H^H^Hphere, but it looks to me that you have a configuration problem. There was a special screen where you'd create credentials (user/pass) and later you'd apply those credentials to the created data source. It looks like that your configured data source hasn't got credentials applied.

mindas
Actually the "Authentication Alias" is set in the datasource, but seems like these credentials are not being applied.
Abel Morelos
+2  A: 

Short answer: external clients don't get to use the authentication alias data

Longer Answer:
From the WAS J2C connection factory documentation:

The alias that you configure for component-managed authentication does not apply to all clients that must access the secured resource. External Java clients with Java Naming and Directory Interface (JNDI) access can look up a Java 2 Connector (J2C) resource such as a data source or Java Message Service (JMS) queue. However, they are not permitted to take advantage of the component-managed authentication alias defined on the resource. This alias is the default value that is used when the getConnection() method does not specify any authentication data, like user and password, or a value for ConnectionSpec. If an external client needs to get a connection, it must assume responsibility for the authentication by passing it through arguments on the getConnection() call.
Dan B
Thanks for the pointer!!! The way I have found to overcome this issue is to provide the user and password as custom properties, this works OK for Sybase (custom properties named "USER" and "PASSWORD" in uppercase) but it's not working for Oracle (custom properties named "user" and "password" in lowercase), I think it's because the Oracle's "password" custom property is being encrypted when entered the first time but it's not unencrypted when when I access the datasource from my external client (but works for any application deployed in WAS). I'll ask a new question for that one, thanks again!
Abel Morelos
A: 

Even after defining the user/password values as custom properties I found that the connections for Oracle weren't working. After many days, I just found that the development server is running an old WAS 6.1 version, the problem I'm having was fixed in WAS 6.1.0.5: PK32838: J2CA0046E WHEN USING USING CUSTOM PROP PASSWORD ON DATASOURECE

I tried my code in a different WAS server with an updated WAS fix pack level and... it worked without introducing a single change in the code or in the configuration. So the solution is to upgrade the WAS server.

Thanks.

Abel Morelos
A: 

Thank you Dan & Abel,

I had same problem connecting to Oracle, just followed Abel sugestion

Resources > JDBC > Datasources > Click on "OracleDS" Under "Additional Properties" section click on "Custom Properties"

create below 2 properties: 1. Name:user Value:xxx

2. Name:password Value:xxX

I could able to access the URL through a stand alone program. Kudos to U guys!!!!!!

-NaveenKumar Siddamsetty

Naveen