【问题标题】:Call to DataSource.getConnection not returning the expected connection调用 DataSource.getConnection 未返回预期的连接
【发布时间】:2010-04-20 17:01:59
【问题描述】:

我有以下代码:

        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();

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

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

对此:conn = ds.getConnection("username","password");

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

如果您对异常感到好奇,对于 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$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)

对于 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$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)

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

感谢您的建议。

【问题讨论】:

    标签: java database jdbc jakarta-ee websphere


    【解决方案1】:

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

    更长的答案:
    来自WAS J2C connection factory documentation:

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

    【讨论】:

    • 感谢指点!!!我发现解决此问题的方法是将用户和密码作为自定义属性提供,这适用于 Sybase(名为“USER”的自定义属性和大写的“PASSWORD”),但不适用于 Oracle(名为“的自定义属性”用户”和“密码”小写),我认为这是因为 Oracle 的“密码”自定义属性在第一次输入时被加密,但当我从外部客户端访问数据源时它不是未加密的(但适用于任何部署的应用程序在 WAS 中)。我会为此提出一个新问题,再次感谢!
    【解决方案2】:

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

    【讨论】:

    • 实际上在数据源中设置了“身份验证别名”,但似乎没有应用这些凭据。
    【解决方案3】:

    即使在将用户/密码值定义为自定义属性之后,我也发现 Oracle 的连接无法正常工作。几天后,我才发现开发服务器运行的是旧的 WAS 6.1 版本,我遇到的问题在 WAS 6.1.0.5 中得到了修复:PK32838: J2CA0046E WHEN USING USING CUSTOM PROP PASSWORD ON DATASOURECE

    我在具有更新的 WAS 修订包级别的不同 WAS 服务器中尝试了我的代码,并且......它在没有对代码或配置进行任何更改的情况下工作。所以解决办法就是升级WAS服务器。

    谢谢。

    【讨论】:

      猜你喜欢
      • 2021-07-15
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 2019-08-29
      相关资源
      最近更新 更多