查找 InitialContext.lookup 检索到的数据源的定义位置?
Find Where Data Source retrieved by InitialContext.lookup is defined?
我正在调试的 JBoss 服务器上 运行 有一些其他人编写的 Java 代码(早已消失,无法联系他们)运行。这行代码得到了 javax.sql.DataSource
:
DataSource ds = new InitialContext().lookup("java:/jdbc/WPDS");
但是,当他们在下一行使用 ds.getConnection()
时,日志中会显示:
...
javax.resource.ResourceException: Unable to get managed connection for jdbc/WPDS
...
Caused by: org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: ORA-01017: invalid username/password; logon denied)
我环顾四周,发现了一个名为 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 日志记录,或者我可以通过某种方式让它告诉我它正在尝试使用什么username/password(这样我就可以看到它是否正在使用文件中的内容?)
您可以尝试像这样获取信息,但不是密码。
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());
}
ORA-01017:无效username/password;登录被拒绝
原因:
尝试登录 Oracle 时输入了无效的用户名或密码。用户名和密码必须与 GRANT CONNECT 语句中指定的相同。如果用户名和密码一起输入,则格式为:username/password。
ORA-01017 错误的核心问题是用户 ID 和密码组合无效,但除了密码不正确,还有用户 ID 问题
可能是目标系统的用户 ID 无效 - 该用户 ID 作为用户名列存在于 dba_users 视图中。
检查您的 $ORACLE_SID 环境参数。如果您的 $ORACLE_SID 设置为错误的系统 ID,那么您可能会收到 ORA-01017 错误,因为您连接到错误的数据库。
检查您的 tnsnames.ora 以确保 TNS 服务名称指向正确的服务器和实例名称。如果指定的 tnsnames.ora 服务名称不正确,则该数据库中可能不存在用户 ID 和密码。
操作:
以正确的格式输入有效的用户名和密码组合。
用户名和密码绝对不正确。
试试 ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE;并更改密码。
http://oracle-base.com/articles/11g/case-sensitive-passwords-11gr1.php
我最终写了一个方法,它递归地反映一个对象并打印很多关于它的信息。
我最终发现它使用的是 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);
我正在调试的 JBoss 服务器上 运行 有一些其他人编写的 Java 代码(早已消失,无法联系他们)运行。这行代码得到了 javax.sql.DataSource
:
DataSource ds = new InitialContext().lookup("java:/jdbc/WPDS");
但是,当他们在下一行使用 ds.getConnection()
时,日志中会显示:
...
javax.resource.ResourceException: Unable to get managed connection for jdbc/WPDS
...
Caused by: org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (java.sql.SQLException: ORA-01017: invalid username/password; logon denied)
我环顾四周,发现了一个名为 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 日志记录,或者我可以通过某种方式让它告诉我它正在尝试使用什么username/password(这样我就可以看到它是否正在使用文件中的内容?)
您可以尝试像这样获取信息,但不是密码。
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());
}
ORA-01017:无效username/password;登录被拒绝
原因:
尝试登录 Oracle 时输入了无效的用户名或密码。用户名和密码必须与 GRANT CONNECT 语句中指定的相同。如果用户名和密码一起输入,则格式为:username/password。
ORA-01017 错误的核心问题是用户 ID 和密码组合无效,但除了密码不正确,还有用户 ID 问题
可能是目标系统的用户 ID 无效 - 该用户 ID 作为用户名列存在于 dba_users 视图中。
检查您的 $ORACLE_SID 环境参数。如果您的 $ORACLE_SID 设置为错误的系统 ID,那么您可能会收到 ORA-01017 错误,因为您连接到错误的数据库。
检查您的 tnsnames.ora 以确保 TNS 服务名称指向正确的服务器和实例名称。如果指定的 tnsnames.ora 服务名称不正确,则该数据库中可能不存在用户 ID 和密码。
操作:
以正确的格式输入有效的用户名和密码组合。
用户名和密码绝对不正确。
试试 ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE;并更改密码。
http://oracle-base.com/articles/11g/case-sensitive-passwords-11gr1.php
我最终写了一个方法,它递归地反映一个对象并打印很多关于它的信息。
我最终发现它使用的是 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);