使用 Tomcat 7 并尝试从 OracleDataSource 对象获取连接时出现 NoClassDefFoundError
NoClassDefFoundError when using Tomcat 7 and trying to getConnection from OracleDataSource object
我想要做的是使用 OracleTranslatingConnection
对象打开到 Oracle Database 12c 服务器的连接,这样我就可以利用我在本地设置的 SQL 翻译框架12c 数据库。
我正在处理的应用程序使用 Java 7 和 Tomcat 7。
如果我在 Tomcat 之外执行下面的代码片段,则会建立连接,simpleQuery
会被正确翻译,并且我会从数据库中获得正确的结果。
但是,如果我使用 Tomcat 执行相同的片段(不包括与上下文相关的所有内容),我在到达行 conn = ods.getConnection()
.
后收到以下异常
当我在 Tomcat 之外执行时,我的类路径中有 ojdbc7.jar
和 asm-3.3.1.jar
(OJDBC 需要 ClassWriter?)。使用 Tomcat 时,jar 位于 Tomcat 的 lib 文件夹中,它们必须可见,因为我能够实例化那些 Oracle 对象。
我从 Oracle's API reference 开始,到 Google 结束,但没有成功找到解决方案。到目前为止,我发现的无用解决方案涉及 ClassNotFoundException
,其中必要的 jars 不在正确的位置,或者重新配置 Tomcat 的 server/web XML 文件(我不应该这样做)不需要,因为我是自己创建数据源,而不是通过上下文查找),或者以不使用 OracleDataSource
的方式连接到数据库。我需要那个特定的对象,这样我就可以设置翻译功能的属性(参见 props.put(...)
行)。
任何人都可以阐明我在这里缺少的东西吗?
异常
java.lang.NoClassDefFoundError: oracle/jdbc/internal/OracleConnection (wrong name: oracle/jdbc/proxy/oraclejdbcbabelfishBabelfishConnectionoraclejdbcinternalOracleConnection$$$Proxy)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.findClass(ClassGenerator.java:326)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.findClass(ClassGenerator.java:326)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.generate(ClassGenerator.java:319)
at oracle.jdbc.proxy.ProxyFactory.prepareProxy(ProxyFactory.java:517)
at oracle.jdbc.proxy.ProxyFactory.createProxy(ProxyFactory.java:479)
at oracle.jdbc.proxy.ProxyFactory.proxyForCache(ProxyFactory.java:272)
at oracle.jdbc.proxy.ProxyFactory.proxyFor(ProxyFactory.java:105)
at oracle.jdbc.proxy.ProxyFactory.proxyFor(ProxyFactory.java:91)
at oracle.jdbc.driver.OracleDriver.babelfishConnect(OracleDriver.java:657)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:561)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:317)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:241)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:184)
at com.example.OracleTest.testOracle(OracleTest.java:60)
代码段
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTranslatingConnection;
import oracle.jdbc.pool.OracleDataSource;
public class OracleTest {
private static String TRANSLATION_PROFILE_NAME = "SQLSERVER_PROFILE";
private static void testOracle() throws SQLException {
String jdbcUrl = "jdbc:oracle:thin:@//server:1521/servicename";
String jdbcUserName = "user";
String jdbcPassword = "pass";
Properties props = new Properties();
OracleDataSource ods = null;
OracleTranslatingConnection trConn = null;
Statement trStmt = null;
Connection conn = null;
ResultSet trRs = null;
String simpleQuery = "SELECT TOP 1 column1 FROM test_table ORDER BY column1 DESC";
ods = new OracleDataSource();
ods.setURL(jdbcUrl);
ods.setUser(jdbcUserName);
ods.setPassword(jdbcPassword);
props.put(OracleConnection.CONNECTION_PROPERTY_SQL_TRANSLATION_PROFILE, TRANSLATION_PROFILE_NAME);
ods.setConnectionProperties(props);
conn = ods.getConnection();
trConn = (OracleTranslatingConnection) conn;
trStmt = trConn.createStatement(true);
trRs = trStmt.executeQuery(simpleQuery);
while (trRs.next()) {
System.out.println("column1: " + trRs.getString(1));
}
trRs.close();
trStmt.close();
conn.close();
}
}
不幸的是,在与 Oracle 开发人员支持人员来回沟通后,确定这是 12.1 之后的版本中要修复的错误,我无法使用查询翻译功能。
我想要做的是使用 OracleTranslatingConnection
对象打开到 Oracle Database 12c 服务器的连接,这样我就可以利用我在本地设置的 SQL 翻译框架12c 数据库。
我正在处理的应用程序使用 Java 7 和 Tomcat 7。
如果我在 Tomcat 之外执行下面的代码片段,则会建立连接,simpleQuery
会被正确翻译,并且我会从数据库中获得正确的结果。
但是,如果我使用 Tomcat 执行相同的片段(不包括与上下文相关的所有内容),我在到达行 conn = ods.getConnection()
.
当我在 Tomcat 之外执行时,我的类路径中有 ojdbc7.jar
和 asm-3.3.1.jar
(OJDBC 需要 ClassWriter?)。使用 Tomcat 时,jar 位于 Tomcat 的 lib 文件夹中,它们必须可见,因为我能够实例化那些 Oracle 对象。
我从 Oracle's API reference 开始,到 Google 结束,但没有成功找到解决方案。到目前为止,我发现的无用解决方案涉及 ClassNotFoundException
,其中必要的 jars 不在正确的位置,或者重新配置 Tomcat 的 server/web XML 文件(我不应该这样做)不需要,因为我是自己创建数据源,而不是通过上下文查找),或者以不使用 OracleDataSource
的方式连接到数据库。我需要那个特定的对象,这样我就可以设置翻译功能的属性(参见 props.put(...)
行)。
任何人都可以阐明我在这里缺少的东西吗?
异常
java.lang.NoClassDefFoundError: oracle/jdbc/internal/OracleConnection (wrong name: oracle/jdbc/proxy/oraclejdbcbabelfishBabelfishConnectionoraclejdbcinternalOracleConnection$$$Proxy)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.findClass(ClassGenerator.java:326)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.findClass(ClassGenerator.java:326)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at oracle.jdbc.proxy.ClassGenerator.generate(ClassGenerator.java:319)
at oracle.jdbc.proxy.ProxyFactory.prepareProxy(ProxyFactory.java:517)
at oracle.jdbc.proxy.ProxyFactory.createProxy(ProxyFactory.java:479)
at oracle.jdbc.proxy.ProxyFactory.proxyForCache(ProxyFactory.java:272)
at oracle.jdbc.proxy.ProxyFactory.proxyFor(ProxyFactory.java:105)
at oracle.jdbc.proxy.ProxyFactory.proxyFor(ProxyFactory.java:91)
at oracle.jdbc.driver.OracleDriver.babelfishConnect(OracleDriver.java:657)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:561)
at oracle.jdbc.pool.OracleDataSource.getPhysicalConnection(OracleDataSource.java:317)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:241)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:184)
at com.example.OracleTest.testOracle(OracleTest.java:60)
代码段
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleTranslatingConnection;
import oracle.jdbc.pool.OracleDataSource;
public class OracleTest {
private static String TRANSLATION_PROFILE_NAME = "SQLSERVER_PROFILE";
private static void testOracle() throws SQLException {
String jdbcUrl = "jdbc:oracle:thin:@//server:1521/servicename";
String jdbcUserName = "user";
String jdbcPassword = "pass";
Properties props = new Properties();
OracleDataSource ods = null;
OracleTranslatingConnection trConn = null;
Statement trStmt = null;
Connection conn = null;
ResultSet trRs = null;
String simpleQuery = "SELECT TOP 1 column1 FROM test_table ORDER BY column1 DESC";
ods = new OracleDataSource();
ods.setURL(jdbcUrl);
ods.setUser(jdbcUserName);
ods.setPassword(jdbcPassword);
props.put(OracleConnection.CONNECTION_PROPERTY_SQL_TRANSLATION_PROFILE, TRANSLATION_PROFILE_NAME);
ods.setConnectionProperties(props);
conn = ods.getConnection();
trConn = (OracleTranslatingConnection) conn;
trStmt = trConn.createStatement(true);
trRs = trStmt.executeQuery(simpleQuery);
while (trRs.next()) {
System.out.println("column1: " + trRs.getString(1));
}
trRs.close();
trStmt.close();
conn.close();
}
}
不幸的是,在与 Oracle 开发人员支持人员来回沟通后,确定这是 12.1 之后的版本中要修复的错误,我无法使用查询翻译功能。