java 调用 DataSource.getConnection 未返回预期的连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2677079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:19:28  来源:igfitidea点击:

Call to DataSource.getConnection not returning the expected connection

javadatabasejdbcjakarta-eewebsphere

提问by Abel Morelos

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.

我在连接到 WAS 6.1.0.3 的独立应用程序中有前面的代码,以便从数据源检索连接。代码非常简单,我已经看到相同的代码在不同的环境中工作,但在这种情况下,当我调用 getConnection 时,我得到了一个异常。数据源是 WAS 具有正确的身份验证别名集,当测试连接时,它可以从 WAS 端正常工作,但以前的代码将不起作用。

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

如果我改变这一行:conn = ds.getConnection();

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

对此: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.

然后代码将起作用!但这不是我想要的,因为数据源中的连接应该已经设置了凭据。我最初认为这是一个 Sybase 问题,但它也发生在 Oracle 上,所以我宁愿说我在 WAS 上有问题。

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

如果您对异常感到好奇,对于 Sybase,我会得到:

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.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:

对于 Oracle,我得到了这个:

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.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

在这两种情况下,如果我将凭据传递给 getConnection 方法,我都不会例外

Thanks for your advice.

谢谢你的建议。

回答by Dan B

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

简短回答:外部客户端无法使用身份验证别名数据

Longer Answer:
From the WAS J2C connection factory documentation:

更长的答案:
来自WAS J2C 连接工厂文档

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.
您为组件管理的身份验证配置的别名不适用于必须访问受保护资源的所有客户端。具有 Java 命名和目录接口 (JNDI) 访问权限的外部 Java 客户端可以查找 Java 2 连接器 (J2C) 资源,例如数据源或 Java 消息服务 (JMS) 队列。但是,不允许它们利用在资源上定义的组件管理的身份验证别名。此别名是当 getConnection() 方法未指定任何身份验证数据(如用户和密码)或 ConnectionSpec 值时使用的默认值。如果外部客户端需要获取连接,它必须通过 getConnection() 调用上的参数传递它来承担身份验证的责任。

回答by mindas

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.

我已经很久没有用 WebSFEAR^H^H^H^Hphere 做过任何事情了,但在我看来,您遇到了配置问题。有一个特殊的屏幕,您可以在其中创建凭据(用户/密码),然后将这些凭据应用于创建的数据源。看起来您配置的数据源尚未应用凭据。

回答by Abel Morelos

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

即使在将用户/密码值定义为自定义属性之后,我发现 Oracle 的连接也不起作用。许多天后,我才发现开发服务器运行的是旧的 WAS 6.1 版本,我遇到的问题在 WAS 6.1.0.5 中得到解决:PK32838:J2CA0046E WHEN USING USING USING USING USING 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.

我在具有更新的 WAS 修复包级别的不同 WAS 服务器中尝试了我的代码,并且......它在代码或配置中没有引入任何更改的情况下工作。所以解决方案是升级WAS服务器。

Thanks.

谢谢。