0

conn= Ds.getConnection(); Connection oraconn = ((DelegatingConnection)conn).getInnermostDelegate();

its giving following exception java.lang.ClassCastException: org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to org.apache.commons.dbcp.DelegatingConnection

I have also set resource parameter accessToUnderlyingConnectionAllowed=true need to unwrapp this object to pass to ArrayDescriptor in server.xml of tomcat please help thanx in advance

Shrikant Dande
  • 85
  • 2
  • 2
  • 9

1 Answers1

0

It might be that your org.apache.commons.dbcp.DelegatingConnection is a different class (different classloader) than the org.apache.commons.dbcp.DelegatingConnection from the connection.

this can be, if you are supplying this class via your container-bound warfile, and the connection is instantiated via tomcat (or other application server).

to test this you can use something like:

Class.forName("org.apache.commons.dbcp.DelegatingConnection").getClassLoader().toString()
conn.getClassLoader().toString();

you might be able ot use reflection. this from a similar question:

// 'source' is from another classloader
Method method = conn.getClass().getMethod("getInnermostDelegate", new Class[] {});
Object o = method.invoke(conn, new Object[] {});

However, i'm not sure the return argument is easily castable to a class in your current classloader. If you follow the reflection method, make absolutely sure you encapsulate all of this in a single class, don't let things like Method and Object bleed out from this. I don't recommend this but it ought to work.

an alternative is to place your code in the same place as the connection. (tomcat lib)

ofcourse first check if indeed you are using 2 different classloaders for your code. :D

EDIT:

From the comments it looks like there are 2 classloaders at work here. I forgot to mention a 3rd approach.

  1. preferred: remove the jar file that supplies DelegatingConnection from your war file and rely on it being supplied by the common/lib classloader.
  2. run your code in the common/lib classloader by placing the war there
  3. reflect : probably bad, probably will give trouble casting the result object to the right class
Community
  • 1
  • 1
Joeblade
  • 1,735
  • 14
  • 22
  • I used this `Sysout("1)"+Class.forName("org.apache.commons.dbcp.DelegatingConnection").getClassLoader().toString()); conn=ds.getConnection(); Sysout("2)"+conn.getClass().getClassLoader().toString());` OP 1)WebappClassLoader delegate: false repositories: /WEB-INF/classes/ ----------> Parent Classloader: StandardClassLoader delegate: true repositories: file:D:\Apache Software Foundation\Tomcat 5.0\shared\classes\ -2) StandardClassLoader delegate: true repositories: file:D:\Apache Software Foundation\Tomcat 5.0\common\classes\ – Shrikant Dande Nov 11 '14 at 11:45
  • yeah that looks like 2 different classloaders to me. the first one is your container's classloader, the second one is it's parent, common/classes, which is shared by all war files. – Joeblade Nov 11 '14 at 15:02
  • you might fix it by not supplying the jar file / class file in WEB-INF/classes and only using the one already supplied in common/classes. If you can identify the specific jar file that you are supplying _and_ is present in the common/lib / common/classes you could exclude it form your war file, hopefully – Joeblade Nov 11 '14 at 15:03
  • I removed commons-dbcp.1.2 jar from workspace lib ,but without importing `org.apache.commons.dbcp.DelegatingConnection` class how can I use this `Connection oraconn = ((DelegatingConnection)conn).getInnermostDelegate(); ` – Shrikant Dande Nov 12 '14 at 06:45
  • You should (probbaly) be able to still import it at runtime from the other classloader. keep your import statement in your code. you can also build against it, but just don't ship the jar file in your WEB-INF/lib folder – Joeblade Nov 12 '14 at 08:23
  • I think it is not possible to import at runtime..giving error `java.lang.Error: Unresolved compilation problems: The import org.apache.commons.dbcp cannot be resolved DelegatingConnection cannot be resolved to a type ` thanx for your suggestions though – Shrikant Dande Nov 12 '14 at 08:39
  • That is compile time, unless you are using a jsp. If you use the library to compile against (so when you generate classes it is there) but exclude it from packaging into the warfile (so in the warfile you put in tomcat, it isn't there), you should be able to run it. If you use maven in your project you can use provided – Joeblade Nov 12 '14 at 08:44
  • yes my project is 'jsp' servlet web app...and sorry but I didn't get your point – Shrikant Dande Nov 12 '14 at 08:49
  • a jsp would (likely) be compiled by tomcat. If your code is being compiled from a jsp then the error you mentioned indicates you don't have access to the appropriate jar file. (though you are receiving runtime objects from it's governing classloader). however the type of code you are writing is something I would normally only expect to be compiled and packaged into a warfile before being placed in tomcat. In that case, I would expect you compile against a set of jarfiles, and then create a distribution warfile in which you package any dependencies. – Joeblade Nov 12 '14 at 08:55
  • My point is that you use it during compilation but you remove it during packaging. (or for testing, delete it from the war/web-inf/lib after you have compiled). – Joeblade Nov 12 '14 at 08:56
  • how is it possible to do it every time...any way thanx for your reply – Shrikant Dande Nov 20 '14 at 12:35
  • if you use maven, then marking the dependency as "provided" should mean it won't get packaged. If you use ant or make or batch script that packages, then you would need to use the specific tool. – Joeblade Nov 20 '14 at 14:19