vrubleuski
unread,Apr 7, 2013, 8:55:22 AM4/7/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to jdbcdslog-discuss
Hi,
I've made a fix in GenericLoggingProxy, and can contribute it if you
find it appropriate.
So basically I've tried to configure this loggable driver with my
application, which use oracle DB. And it first failed on the line
where someone was getting OracleConnection from JBoss wrapped
connection using method getUnderlyingConnection if I understood that
correct. And then was an attempt to cast getUnderlyingConnection
result to OracleConnection which failed because it was a Proxy with
the only interface Connection. So my first part of fix adds more
interfaces to the loggable wrappers (see getAllInterfaces ).
And another issue arose after first one was fixed. The application
uses some oracle specific classes, like oracle.sql.ARRAY, which
invokes physicalConnectionWithin on connection and expects something
as good as oracle T4CConnection. So I've decided to allow it to access
this real thing, to avoid application failures with a price of loosing
loggability in such a tricky places as that.
Only this class was changed as a result(both fixes are here):
package org.jdbcdslog;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class GenericLoggingProxy implements InvocationHandler {
static Logger logger =
LoggerFactory.getLogger(GenericLoggingProxy.class);
static List methodsBlackList = Arrays.asList(new String[]
{"getAutoCommit", "getCatalog", "getTypeMap"
, "clearWarnings", "setAutoCommit", "getFetchSize", "setFetchSize",
"commit"});
String sql = null;
Object target = null;
public Object getProxyTarget(){
return target;
}
public GenericLoggingProxy(Object target) {
this.target = target;
}
public GenericLoggingProxy(Object target, String sql) {
this.target = target;
this.sql = sql;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
try {
Object r = method.invoke(target, args);
if(method.getName().equals("prepareCall") ||
method.getName().equals("prepareStatement"))
r = wrap(r, (String)args[0]);
else if(method.getName().equals("physicalConnectionWithin"))
r = target;
else
r = wrap(r, null);
return r;
} catch(Throwable t) {
LogUtils.handleException(t, ConnectionLogger.getLogger()
, LogUtils.createLogEntry(method, null, null, null));
}
return null;
}
private Object wrap(Object r, String sql) throws Exception {
if(r instanceof Connection) {
Connection con = (Connection)r;
if(ConnectionLogger.isInfoEnabled())
ConnectionLogger.info("connect to URL " +
con.getMetaData().getURL() + " for user "
+ con.getMetaData().getUserName());
return wrapByGenericProxy(r, sql);
}
if(r instanceof CallableStatement)
return wrapByCallableStatementProxy(r, sql);
if(r instanceof PreparedStatement)
return wrapByPreparedStatementProxy(r, sql);
if(r instanceof Statement)
return wrapByStatementProxy(r);
if(r instanceof ResultSet)
return ResultSetLoggingProxy.wrapByResultSetProxy((ResultSet)r);
return r;
}
private Object wrapByStatementProxy(Object r) {
return Proxy.newProxyInstance(r.getClass().getClassLoader(),
getAllInterfaces(r.getClass()),
new StatementLoggingProxy((Statement)r));
}
private Object wrapByPreparedStatementProxy(Object r, String sql) {
return Proxy.newProxyInstance(r.getClass().getClassLoader(),
getAllInterfaces(r.getClass()),
new PreparedStatementLoggingProxy((PreparedStatement)r, sql));
}
private Object wrapByCallableStatementProxy(Object r, String sql) {
return Proxy.newProxyInstance(r.getClass().getClassLoader(),
getAllInterfaces(r.getClass()),
new CallableStatementLoggingProxy((CallableStatement)r, sql));
}
static Object wrapByGenericProxy(Object r, String sql) {
return Proxy.newProxyInstance(r.getClass().getClassLoader(),
getAllInterfaces(r.getClass()),
new GenericLoggingProxy(r, sql));
}
static Class[] getAllInterfaces(Class theClass){
List allInterfaceList = new ArrayList(5);
Class currentClass = theClass;
while (currentClass != null){
Class[] iList = currentClass.getInterfaces();
for (int i = 0; i < iList.length; i++) {
allInterfaceList.add(iList[i]);
}
currentClass = currentClass.getSuperclass();
}
return (Class[])allInterfaceList.toArray(new
Class[allInterfaceList.size()]);
}
}