Java Apache Commons DBCP 连接对象问题,线程:org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper 中的 ClassCastExceptio
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6489514/
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
Apache Commons DBCP connection object problem, Thread: ClassCastException in org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
提问by Prodigy
I am using Apache Commons DBCP (commons-dbcp.jar
) Connection pool.
我正在使用 Apache Commons DBCP ( commons-dbcp.jar
) 连接池。
Once I obtained a connection from the pool it is wrapped in the
class org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
.
一旦我从池中获得了一个连接,它就会被包装在 class 中org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
。
My requirement is to pass an array of Strings to pl/sql stored procedure in Oracle.
我的要求是将字符串数组传递给 Oracle 中的 pl/sql 存储过程。
Here is what I am doing in the following code snippet:
这是我在以下代码片段中所做的:
Connection dbConn = ConnectionManager.ds.getConnection();
//The above statement returns me an connection wrapped in the class
//org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.
org.apache.commons.dbcp.DelegatingConnection del = new org.apache.commons.dbcp.DelegatingConnection(dbConn.getConnection());
con = del.getInnermostDelegate();
cs = con.prepareCall("call SP_NAME(?,?,?,?)");
oracle.sql.ArrayDescriptor arDesc= oracle.sql.ArrayDescriptor.createDescriptor("ARRAY_NAME", (OracleConnection) con);
CallableStatement c_stmt = conn.prepareCall("begin update_message_ids_ota
(:x); end;" );
c_stmt.setArray( 1, array_to_pass );
c_stmt.execute();
On executing the above code, I get the following exception:
在执行上面的代码时,我得到以下异常:
java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection at oracle.sql.ArrayDescriptor.createDescriptor
java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper 不能转换为 oracle.jdbc.OracleConnection at oracle.sql.ArrayDescriptor.createDescriptor
I tried to find out solution over this going throughout almost of the sites and forums, but couldn't get the satisfied answer or solution on the same.
我试图在几乎所有网站和论坛中找到解决方案,但无法获得满意的答案或解决方案。
回答by Thilo
By default, DBCP does not allow access to the "real" underlying database connection instance, so you cannot get to the Oracle class.
默认情况下,DBCP 不允许访问“真正的”底层数据库连接实例,因此您无法访问 Oracle 类。
When configuringthe pool, you can set
当配置池,可以设置
accessToUnderlyingConnectionAllowed = true
and then it works.
然后它起作用了。
Default is false, it is a potential dangerous operation and misbehaving programs can do harmful things. (closing the underlying or continue using it when the guarded connection is already closed) Be careful and only use when you need direct access to driver specific extensions
NOTE: Do not close the underlying connection, only the original one.
默认为 false,这是一个潜在的危险操作,行为不端的程序可能会做有害的事情。(在受保护的连接已经关闭时关闭底层或继续使用它)小心并且仅在需要直接访问驱动程序特定扩展时使用
注意:不要关闭底层连接,只关闭原始连接。
回答by Harald Scheckenbacher
I'm positing this here to make sure anyone else looking for advice knows about the ultimate solution to this:
我在这里提出这个是为了确保其他寻求建议的人都知道这个问题的最终解决方案:
If you're forced to use the non bundled version of the persistence manager (because an old repository still uses that structure which is incompatible with the bundled layout), here what you can do, the solution is quite simple:
如果您被迫使用持久性管理器的非捆绑版本(因为旧存储库仍然使用与捆绑布局不兼容的结构),那么您可以这样做,解决方案非常简单:
Download the sources for Hymanrabbit Core (you can get them from the Hymanrabbit website) Open the OraclePersistenceManager class and find the following line of code:
下载 Hymanrabbit Core 的源代码(您可以从 Hymanrabbit 网站获取它们) 打开 OraclePersistenceManager 类并找到以下代码行:
Object blob = createTemporary.invoke(null,
new Object[]{con, Boolean.FALSE, durationSessionConstant});
(Around line 377 - can also check the StackTrace for reference)
(在第 377 行附近 - 也可以检查 StackTrace 以供参考)
ConnectionFactory contains a static method that allows to unwrap a connection which is exactly what you need:
ConnectionFactory 包含一个静态方法,它允许解开一个你需要的连接:
Object blob = createTemporary.invoke(null,
new Object[]{org.apache.Hymanrabbit.core.util.db.ConnectionFactory
.unwrap(con), Boolean.FALSE, durationSessionConstant});
You will need Maven 2+ in order to compile the sources, I did that and had no dependency problems, note that I compiled version 2.2.10 of Hymanrabbit.
您将需要 Maven 2+ 才能编译源代码,我这样做了并且没有依赖性问题,请注意,我编译了 Hymanrabbit 的 2.2.10 版。
I also made sure to log a bug against Hymanrabbit 2.2.11 (current release which still has the issue): https://issues.apache.org/jira/browse/JCR-3262
我还确保记录了一个针对 Hymanrabbit 2.2.11(仍然存在问题的当前版本)的错误:https: //issues.apache.org/jira/browse/JCR-3262
Hope this helps!
希望这可以帮助!
回答by Rui Zha
Hmmm,I have meet the same solution like you.I think there a two position need you mention it. 1.Config Connection pool set accessToUnderlyingConnectionAllowed = "true" ; 2.The nightmare concerned to open source project. The terrable conceration. In this case,that is
嗯,我也遇到过和你一样的解决办法。我觉得有两个位置需要你提一下。1.Config 连接池设置 accessToUnderlyingConnectionAllowed = "true" ; 2.关于开源项目的噩梦。可怕的关注。在这种情况下,即
org.apache.commons.dbcp.DelegatingConnection
is not equal to
不等于
org.apache.tomcat.dbcp.dbcp.DelegatingConnection
while in default apache common-dbcp.jar,you will never find the follow Class.But just the class is the key. So,we must find the Class in somewhere. I final find the package tomcat-dbcp.jar . You can get it from http://www.docjar.com/After
而在默认的 apache common-dbcp.jar 中,你永远找不到后续的 Class。但只有 class 才是关键。所以,我们必须在某个地方找到 Class。我最终找到了包tomcat-dbcp.jar 。你可以从http://www.docjar.com/得到它 之后
import org.apache.tomcat.dbcp.dbcp.DelegatingConnection
,you can force cast you dbConn and get the Underlying Connection
,您可以强制转换 dbConn 并获取底层连接
oracle.jdbc.driver.OracleConnection delConn =
(oracle.jdbc.driver.OracleConnection)
((org.apache.tomcat.dbcp.dbcp.DelegatingConnection)c_stmt.getConnection()).getDelegate();
Then we can use delConn to get the ArrayDescriptor Remember one thing,in there,we do not need the
然后我们可以使用 delConn 来获取 ArrayDescriptor 记住一件事,在那里,我们不需要
org.apache.commons.dbcp.DelegatingConnection Class
It's a so strange thing,but real work to the case.
这是一件很奇怪的事情,但对这个案子来说是真正的工作。
回答by Leonardo Eloy
Seen this post i can get the OracleConnection with this code:
看到这篇文章,我可以使用以下代码获得 OracleConnection:
DataSource ds1 = // get the org.apache.commons.dbcp.PoolingDataSource
org.apache.tomcat.dbcp.dbcp.DelegatingConnection del = new org.apache.tomcat.dbcp.dbcp.DelegatingConnection(cds1.getConnection());
OracleConnection con = (OracleConnection) del.getInnermostDelegate();
remember the commons-dbcp-1.4.jar neet to be in the class path
记住 commons-dbcp-1.4.jar neet 要在类路径中
回答by chinto
We use arrays in our calls to oracle stored procs and use oracle proprietary api to build arrays. This little check fixed the issue for us when using the functionality from stand alone apps using commons-dbcp.
我们在调用 oracle 存储过程时使用数组,并使用 oracle 专有 api 来构建数组。这个小检查为我们解决了使用 commons-dbcp 的独立应用程序的功能时的问题。
if (conn instanceof org.apache.commons.dbcp.DelegatingConnection)
{
log.debug("detected apache commons dbcp datasource");
conn = ((org.apache.commons.dbcp.DelegatingConnection) conn).getInnermostDelegate();
}
You will need commons-dbcp in the classpath/dependecies though.
不过,您将需要在类路径/依赖项中使用 commons-dbcp。
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
<scope>provided</scope>
</dependency>
回答by Jeff Olson
If you are using a Java 6 compliant JDBC Connection, you can use code like the following:
如果您使用的是符合 Java 6 的 JDBC 连接,则可以使用如下代码:
OracleConnection oracleConnection = null;
try {
if (connection.isWrapperFor(OracleConnection.class)) {
oracleConnection = connection.unwrap(OracleConnection.class);
}
} catch (SQLException ex) {
// do something
}
return oracleConnection;
From this point on, use the oracleConnection
instead of the original connection
.
从现在开始,使用oracleConnection
代替原来的connection
。
See http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.html
请参阅http://docs.oracle.com/javase/6/docs/api/java/sql/Wrapper.html
回答by Sherin Syriac
I had encountered the same issue. We were using spring and it has a class called NativeJdbcExtractor. It has many implementations and the following one works for TomCat. There are specific implementations for Websphere,Weblogic app servers.
我遇到了同样的问题。我们使用的是 spring,它有一个名为 NativeJdbcExtractor 的类。它有许多实现,下面的一个适用于 TomCat。Websphere、Weblogic 应用服务器有具体的实现。
<bean id="jdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"></bean>
In your DAO you can inject the bean and use the following method
在您的 DAO 中,您可以注入 bean 并使用以下方法
protected NativeJdbcExtractor jdbcExtractor;
Connection conn=jdbcExtractor.getNativeConnection(oracleConnection);
回答by ibrahimbayer
in your context definition add below tags to your existing xml definition.
在您的上下文定义中,将以下标签添加到您现有的 xml 定义中。
factory="oracle.jdbc.pool.OracleDataSourceFactory
scope="Shareable"
type="oracle.jdbc.pool.OracleDataSource"
.
.
回答by Severus Snape
For anyone else looking, getDelegate()
and getInnermostDelegate()
both return NULL
in my code. However, from the debugger I found the OracleConnection as below. We use Spring JdbcTemplate throughout the application, which has the data source injected. We're on spring-jdbc-4.1.5.RELEASE.jar and ojdbc6.jar.
对于其他人看,getDelegate()
并且getInnermostDelegate()
都返回NULL
在我的代码。但是,从调试器中,我发现了 OracleConnection,如下所示。我们在整个应用程序中使用 Spring JdbcTemplate,其中注入了数据源。我们在 spring-jdbc-4.1.5.RELEASE.jar 和 ojdbc6.jar 上。
Connection conn = getJdbcTemplate().getDataSource().getConnection();
OracleConnection oracleConnection = ( OracleConnection ) conn.getMetaData().getConnection();
回答by ashutosh singh
I am working with tomcat 8.5.8 and was facing this issue.
The below solution worked like charm.
我正在使用 tomcat 8.5.8 并面临这个问题。
下面的解决方案很有魅力。
The Code:
编码:
Delegating Connection delegate_conn = new Delegating Connection(connection)
conn = delegate_conn.getInnermostDelegate();
oracle.sql.ArrayDescriptor desc = oracle.sql.ArrayDescriptor.createDescriptor("TABLE_VIEW", conn);
The Solution:
解决方案:
Adding dependency for tomcat-dbcp 8.5.8
and add the same jar in lib folder of tomcat.
Seems tomcat has different jars for different versions starting from 7.0 (reference: https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp).
tomcat-dbcp 8.5.8
为tomcat的lib文件夹添加依赖并添加相同的jar。
似乎 tomcat 从 7.0 开始的不同版本有不同的 jar(参考:https: //mvnrepository.com/artifact/org.apache.tomcat/tomcat-dbcp)。
Hope it helps someone.
希望它可以帮助某人。