我在我调试的JBoss服务器上运行了一些由其他人编写的Java代码(很久以前,无法联系他们)。它使用这一行代码获得javax.sql.DataSource
:
DataSource ds = new InitialContext().lookup("java:/jdbc/WPDS");
但是,当他们在下一行使用ds.getConnection()
时,会显示在日志中:
...
javax.resource.ResourceException:无法获取jdbc / WPDS的托管连接
...
引起:org.jboss.resource.JBossResourceException:无法创建连接; - 嵌套throwable:(java.sql.SQLException:ORA-01017:用户名/密码无效;登录被拒绝)
我环顾四周,发现了一个名为oracle-xa-ds.xml
的文件。它包含这个:
<datasources>
<xa-datasource>
<jndi-name>jdbc/WPDS</jndi-name>
<!-- uncomment to enable interleaving <interleaving/> -->
<isSameRM-override-value>false</isSameRM-override-value>
<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
<xa-datasource-property name="URL">jdbc:oracle:thin:@hostname.hidden.com:1621:HIDE</xa-datasource-property>
<xa-datasource-property name="User">hidden</xa-datasource-property>
<xa-datasource-property name="Password">hidden</xa-datasource-property>
<!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
<!-- Checks the Oracle error codes and messages for fatal errors -->
<exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
<!-- Oracles XA datasource cannot reuse a connection outside a transaction once enlisted in a global transaction and vice-versa -->
<no-tx-separate-pools/>
<max-pool-size>50</max-pool-size>
<!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
<metadata>
<type-mapping>Oracle9i</type-mapping>
</metadata>
</xa-datasource>
<mbean code="org.jboss.resource.adapter.jdbc.vendor.OracleXAExceptionFormatter"
name="jboss.jca:service=OracleXAExceptionFormatter">
<depends optional-attribute-name="TransactionManagerService">jboss:service=TransactionManager</depends>
</mbean>
</datasources>
我已经确认所有这些设置都是正确的。我可以使用此文件中给出的主机名,端口,SID,用户名和密码连接到数据库。
我怀疑它可能是从其他地方加载DataSource
,但我不知道如何检查这个理论(如果它是真的,我该怎么办?找出它实际上从哪里获得它?)我可以启用某种JNDI日志记录,或者我可以以某种方式让它告诉我它尝试使用的用户名/密码(所以我可以看看它是否使用了文件中的内容?)
答案 0 :(得分:1)
ORA-01017:用户名/密码无效;登录被拒绝
原因:
尝试登录Oracle时输入了无效的用户名或密码。用户名和密码必须与GRANT CONNECT语句中指定的相同。如果一起输入用户名和密码,则格式为:用户名/密码。
ORA-01017错误的核心问题是无效的用户ID和密码组合,但除了错误的密码之外,还有用户ID问题
可能是目标系统的用户ID无效 - 用户ID在dba_users视图中作为用户名列存在。
检查$ ORACLE_SID环境参数。如果您的$ ORACLE_SID设置为错误的系统ID,那么您可能会收到ORA-01017错误,因为您连接的是错误的数据库。
检查tnsnames.ora以确保TNS服务名称指向正确的服务器和实例名称。如果指定了错误的tnsnames.ora服务名称,则该数据库中可能不存在用户标识和密码。
行动:
以正确的格式输入有效的用户名和密码组合。
用户和密码完全不正确。
尝试ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE;并改变密码。
http://oracle-base.com/articles/11g/case-sensitive-passwords-11gr1.php
答案 1 :(得分:0)
您可以尝试获取此类信息,但不能获取密码。
if (dataSource instanceof oracle.jdbc.xa.client.OracleXADataSource) {
oracle.jdbc.xa.client.OracleXADataSource oracleXADataSource = (oracle.jdbc.xa.client.OracleXADataSource)dataSource;
logger.info(oracleXADataSource.getUrl());
logger.info(oracleXADataSource.getUsername());
}
答案 2 :(得分:0)
我最后写了一个方法,它递归地反映了一个对象并打印了很多关于它的东西。
我最终发现它使用了来自oracle-xa-ds.xml
的完全相同的密码 - 问题是该文件中的密码不正确。所以我用了不正确的密码浪费了整整两天。
希望这段代码可以帮助其他人快速结束他们的疯狂追逐并让他们回到正确的方向:
public static final void logFields(Object o, String prefix, int depth) {
if (depth <= 0) {
logger.debug(prefix + "No deeper because max depth reached.");
return;
}
if (o == null) {
return;
}
Class c = o.getClass();
String className = c.getName();
if (className.startsWith("java.lang")) {
logger.debug(prefix + "No deeper because class is " + className);
return;
}
logger.debug(prefix + "Class Name: " + className);
for (Field f : c.getDeclaredFields()) {
logger.debug(prefix + "Field Name: " + f.getName());
logger.debug(prefix + "Field Type: " + f.getType());
try {
if (!f.isAccessible()) {
logger.debug(prefix + " Not accessible - fixing that.");
f.setAccessible(true);
logger.debug(prefix + " Should now be accessible.");
}
Object o2 = f.get(o);
logger.debug(prefix + "Field Value: " + o2);
logFields(o2, prefix + " ", depth - 1);
} catch (Throwable t) {
logger.debug(prefix + "Caught Throwable trying to get Field Value: " + t);
logger.error(t, t);
}
}
}
要使用它,只需执行以下操作:
logFields(ds, "", 7);