Sql C3P0,rawConnectionOperation()&;java.lang.IllegalArgumentException

Sql C3P0,rawConnectionOperation()&;java.lang.IllegalArgumentException,sql,c3p0,db2-400,jt400,Sql,C3p0,Db2 400,Jt400,我正在尝试使用一个非标准方法getServerJobIdentifier(),它是IBM Java工具箱(jt400.jar)的一部分,类com.IBM.as400.access.as400jdbconnection和C3P0&rawConnectionOperation()。我得到“java.lang.IllegalArgumentException:对象不是声明类的实例”。我尝试了许多选择,但没有找到正确的参数来通过。我使用的是C3P00.9.5.4。代码片段如下所示: // The met

我正在尝试使用一个非标准方法getServerJobIdentifier(),它是IBM Java工具箱(jt400.jar)的一部分,类com.IBM.as400.access.as400jdbconnection和C3P0&rawConnectionOperation()。我得到“java.lang.IllegalArgumentException:对象不是声明类的实例”。我尝试了许多选择,但没有找到正确的参数来通过。我使用的是C3P00.9.5.4。代码片段如下所示:

// The method I want to call.
// getServerJobIdentifier, public abstract java.lang.String com.ibm.as400.access.AS400JDBCConnection.getServerJobIdentifier()
String driverClassName = "com.ibm.as400.access.AS400JDBCDriver";
String m_DatabaseConnectionString = "jdbc:db2:*local;naming=sql;extended metadata=true";
Connection m_dbConnection;
ComboPooledDataSource   m_cpds;

m_cpds = new ComboPooledDataSource();
try {
    m_cpds.setDriverClass(driverClassName); //loads the jdbc driver
}
catch (Exception e) {
    e.printStackTrace();
    System.exit(0);
}
m_cpds.setJdbcUrl(m_DatabaseConnectionString);

m_dbConnection = m_cpds.getConnection();
String qualifiedName = "";
C3P0ProxyConnection castCon = (C3P0ProxyConnection)m_dbConnection;
Method m = AS400JDBCConnection.class.getDeclaredMethod("getServerJobIdentifier");
// This does return what I want.  getServerJobIdentified() has no parameters.
System.out.println("method=" + m.toString());
Object[] args = new Object[] {};

System.out.println("calling rawConnectionOperation");

qualifiedName = (String) castCon.rawConnectionOperation(m, C3P0ProxyConnection.RAW_CONNECTION, args);
// never gets here
System.out.println("qualifiedName=" + qualifiedName);
我知道我已经很接近了,或者我认为我已经接近了。谢谢

import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import com.mchange.v2.c3p0.*;

import com.ibm.as400.access.AS400;
import com.ibm.as400.access.AS400JDBCConnection;
import com.ibm.as400.access.AS400SecurityException;
import com.ibm.db2.jdbc.app.DB2Connection;

// javac -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar C3P0Main.java
// /QIBM/ProdData/OS400/jt400/lib/jt400Native.jar
// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar C3P0Main
// or
// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:/QIBM/ProdData/OS400/jt400/lib/jt400Native.jar C3P0Main

// c3p0.acquireRetryAttempts=0
// c3p0.acquireRetryDelay=5000
// c3p0.breakAfterAcquireFailure=false

// c3p0.maxConnectionAge=10800
// c3p0.maxIdleTime=3600
// c3p0.maxIdleTimeExcessConnections=600

// c3p0.automaticTestTable=c3p0test
// c3p0.idleConnectionTestPeriod=600
// c3p0.testConnectionOnCheckout=true

// java -cp :./c3p0-0.9.5.4.jar:./mchange-commons-java-0.2.15.jar:./jt400.jar -Dc3p0.acquireRetryAttempts=0 -Dc3p0.acquireRetryDelay=5000 -Dc3p0.breakAfterAcquireFailure=false -Dc3p0.maxConnectionAge=10800 -Dc3p0.maxIdleTime=3600 -Dc3p0.maxIdleTimeExcessConnections=600 -Dc3p0.automaticTestTable=c3p0test -Dc3p0.idleConnectionTestPeriod=600 -Dc3p0.testConnectionOnCheckout=true C3P0Main

public class C3P0Main {
    private Connection m_dbConnection;
    private ComboPooledDataSource   m_cpds;
    private String driverClassName = "com.ibm.as400.access.AS400JDBCDriver";
    //private String m_DatabaseConnectionString = "jdbc:as400:BNADEV;naming=sql;extended metadata=true;user=beak;password=roatan12";
    private String m_DatabaseConnectionString = "jdbc:as400:BNADEV;naming=sql;extended metadata=true";
    private String m_databaseServerJobID;

    public C3P0Main() throws SQLException
    {
        m_cpds = new ComboPooledDataSource();
        try {
            m_cpds.setDriverClass(driverClassName); //loads the jdbc driver
        }
        catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
        m_cpds.setJdbcUrl(m_DatabaseConnectionString);
    }

    public void run(String[] args) throws Exception
    {
        m_dbConnection = m_cpds.getConnection();
        System.out.println("m_dbConnection=" + m_dbConnection.toString());

        String qualifiedName = "";
        try {
            // To use it, first cast the returned Connection to a C3P0ProxyConnection.
            // Then call the method rawConnectionOperation, supplying the java.lang.reflect.Method object
            // for the non-standard method you wish to call as an argument. The Method you supply will
            // be invoked on the target you provide on the second argument (null for static methods),
            // and using the arguments you supply in the third argument to that function. For the target,
            // and for any of the method arguments, you can supply the special token
            // C3P0ProxyConnection.RAW_CONNECTION, which will be replaced with the
            // underlying vendor-specific Connection object before the Method is invoked.
            //
            // C3P0ProxyConnection castCon = (C3P0ProxyConnection) c3p0DataSource.getConnection();
            // Method m = CLOB.class.getMethod("createTemporary", new Class[]{Connection.class, boolean.class, int.class});
            // Object[] args = new Object[] {C3P0ProxyConnection.RAW_CONNECTION, Boolean.valueOf( true ), new Integer( 10 )};
            // CLOB oracleCLOB = (CLOB) castCon.rawConnectionOperation(m, null, args);

            // getServerJobIdentifier, public abstract java.lang.String com.ibm.as400.access.AS400JDBCConnection.getServerJobIdentifier()

            System.out.println("Is a wrapper for DB2Connection=" + m_dbConnection.isWrapperFor(com.ibm.db2.jdbc.app.DB2Connection.class));
            System.out.println("Is a wrapper for AS400JDBCConnection=" + m_dbConnection.isWrapperFor(AS400JDBCConnection.class));

            C3P0ProxyConnection castCon = (C3P0ProxyConnection)m_dbConnection;

            System.out.println("C3P0ProxyConnection.RAW_CONNECTION=" + C3P0ProxyConnection.RAW_CONNECTION.getClass().getName());

            Method method = AS400JDBCConnection.class.getMethod("getServerJobIdentifier");

            System.out.println("method=" + method.toString());
            Object[] method_args = new Object[] {};

            System.out.println("calling rawConnectionOperation");

            try {
                qualifiedName = (String) castCon.rawConnectionOperation(method, m_dbConnection, method_args);
                System.out.println("qualifiedName=" + qualifiedName);
            }
            catch (IllegalArgumentException | SQLException | InvocationTargetException | IllegalAccessException e) {
                System.out.println(e);
                System.out.println("oh well #1.");
            }

            try {
                Object[] method_args = new Object[] {};
                qualifiedName = (String) castCon.rawConnectionOperation(method, m_dbConnection, method_args);
                System.out.println("qualifiedName=" + qualifiedName);
            }
            catch (IllegalArgumentException | SQLException | InvocationTargetException | IllegalAccessException e) {
                System.out.println(e);
                System.out.println("oh well #2.");
            }

            if (castCon instanceof AS400JDBCConnection) {
                System.out.println("YES");
                qualifiedName = ((AS400JDBCConnection)C3P0ProxyConnection.RAW_CONNECTION).getServerJobIdentifier();
                String jobName = qualifiedName.substring(0, 10).trim();
                String jobUser = qualifiedName.substring(10, 20).trim();
                String jobNumber = qualifiedName.substring(20).trim();
                m_databaseServerJobID = jobNumber + '/' + jobUser + '/' + jobName;
                System.out.println("SQL Server Job ID: " + m_databaseServerJobID);
            }
            else {
                System.out.println("m_dbConnection is not an instance of DB2Connection.");
            }
        }
        catch (IllegalArgumentException | SQLException | NoSuchMethodException e) {
            System.out.println(e);
            System.out.println("oh well.");
        }
    }

    public static void main(java.lang.String args[])
    {
        try {
            C3P0Main app = new C3P0Main();
            app.run(args);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

在我看来,AS400JDBCConnection必须是包装类,但不知何故,它可能不是。我至少想知道如何从C3P0中获取该类,但这是我正在研究的另一件事。我不知道为什么这样做不起作用,但JDBC4添加了一种替代方法来获取底层连接,这可能更容易。(原始连接操作对于语句/结果集返回方法仍然很有用,因此c3p0可以清理它们,但这不是您的情况。)如果尝试
m_dbConnection.unwrap(as400jdbconnection.class)
,会发生什么情况?最好是使用一个查询方法,告诉您底层类是什么,而不必猜测。我认为类似System.out.println(“C3P0ProxyConnection.RAW_CONNECTION=“+C3P0ProxyConnection.RAW_CONNECTION.getClass().getName());除了“java.lang.Object”之外,您可以尝试
Connection c=m_dbConnection.unwrap(Connection.class);System.out.println(c.getClass().getName())我认为这可能是发生的事情,但后来我认为不可能,但返回的类是com.ibm.db2.jdbc.app.DB2Connection,而不是as400jdbconnection。奇怪的是,当我“jar-tvf”所有jar文件时,DB2Connection不会出现,而as400jdbconnection会出现。我得挖得更深一点。谢谢你的提示。