2015-10-13 79 views
2

當服務器運行時,它試圖檢測jdbc方法。我嘗試了setString,setInt方法和executeQuery方法,同時運行一個簡單的mysql查詢,因爲它在JDBC示例中給出。當我通過注入下面一行來測試setString方法時,它工作的很好。Javasist在檢測org.h2.jdbc.JdbcPreparedStatement的setString方法時拋出javassist.CannotCompileException

private void injectSetVariableMethods(CtMethod method) { 
     if (isInEnum(method.getName().toUpperCase(), SetMethods.class)) { 
      try { 
       method.insertAt(1, true, 
         "javaagent.JDBCPublisher.fillArrayList(String.valueOf($2), " + 
         "Thread.currentThread().getStackTrace()[1].getMethodName().toUpperCase());" 
       ); 
      } catch (CannotCompileException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

但是現在,當我使用h2服務器運行它時,它給出以下例外。

javassist.CannotCompileException: by javassist.bytecode.BadBytecode: setString (ILjava/lang/String;)V in org.h2.jdbc.JdbcPreparedStatement: failed to resolve types 
    at javassist.CtBehavior.insertAt(CtBehavior.java:1210) 
    at javaagent.JDBCTransformer.injectSetVariableMethods(JDBCClassTransformer.java:212) 
    at javaagent.JDBCTransformer.transform(JDBCClassTransformer.java:99) 
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188) 
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:424) 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.defineClass(DefaultClassLoader.java:188) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClassHoldingLock(ClasspathManager.java:638) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.defineClass(ClasspathManager.java:613) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findClassImpl(ClasspathManager.java:574) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClassImpl(ClasspathManager.java:492) 
    at org.eclipse.osgi.baseadaptor.loader.ClasspathManager.findLocalClass(ClasspathManager.java:465) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.findLocalClass(DefaultClassLoader.java:216) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findLocalClass(BundleLoader.java:395) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:464) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421) 
    at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412) 
    at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358) 
    at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:234) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:126) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 
    at org.carbon.ndatasource.rdbms.ConnectionRollbackOnReturnInterceptor.invoke(ConnectionRollbackOnReturnInterceptor.java:51) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:67) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 
    at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:153) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 
    at org.apache.tomcat.jdbc.pool.TrapException.invoke(TrapException.java:41) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:109) 
    at org.apache.tomcat.jdbc.pool.DisposableConnectionFacade.invoke(DisposableConnectionFacade.java:80) 
    at com.sun.proxy.$Proxy18.prepareStatement(Unknown Source) 
    at org.carbon.user.core.claim.dao.ClaimDAO.getDialectCount(ClaimDAO.java:160) 
    at org.carbon.user.core.common.DefaultRealm.populateProfileAndClaimMaps(DefaultRealm.java:429) 
    at org.carbon.user.core.common.DefaultRealm.init(DefaultRealm.java:105) 
    at org.carbon.user.core.common.DefaultRealmService.initializeRealm(DefaultRealmService.java:230) 
    at org.wso2.carbon.user.core.common.DefaultRealmService.<init>(DefaultRealmService.java:96) 
    at org.wso2.carbon.user.core.common.DefaultRealmService.<init>(DefaultRealmService.java:109) 
    at org.carbon.user.core.internal.Activator.startDeploy(Activator.java:68) 
    at org.wso2.carbon.user.core.internal.BundleCheckActivator.start(BundleCheckActivator.java:61) 
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl$1.run(BundleContextImpl.java:711) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(BundleContextImpl.java:702) 
    at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(BundleContextImpl.java:683) 
    at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:381) 
    at org.eclipse.osgi.framework.internal.core.AbstractBundle.resume(AbstractBundle.java:390) 
    at org.eclipse.osgi.framework.internal.core.Framework.resumeBundle(Framework.java:1176) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:559) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.resumeBundles(StartLevelManager.java:544) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.incFWSL(StartLevelManager.java:457) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.doSetStartLevel(StartLevelManager.java:243) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:438) 
    at org.eclipse.osgi.framework.internal.core.StartLevelManager.dispatchEvent(StartLevelManager.java:1) 
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) 
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340) 
Caused by: javassist.bytecode.BadBytecode: setString (ILjava/lang/String;)V in org.h2.jdbc.JdbcPreparedStatement: failed to resolve types 
    at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:111) 
    at javassist.bytecode.MethodInfo.rebuildStackMap(MethodInfo.java:423) 
    at javassist.bytecode.MethodInfo.rebuildStackMapIf6(MethodInfo.java:405) 
    at javassist.CtBehavior.insertAt(CtBehavior.java:1200) 
    ... 59 more 
Caused by: javassist.bytecode.BadBytecode: failed to resolve types 
    at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:169) 
    at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:108) 
    ... 62 more 
Caused by: javassist.NotFoundException: org.h2.value.ValueNull 
    at javassist.ClassPool.get(ClassPool.java:450) 
    at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes2(TypeData.java:345) 
    at javassist.bytecode.stackmap.TypeData$TypeVar.fixTypes(TypeData.java:330) 
    at javassist.bytecode.stackmap.TypeData$TypeVar.dfs(TypeData.java:274) 
    at javassist.bytecode.stackmap.MapMaker.fixTypes(MapMaker.java:394) 
    at javassist.bytecode.stackmap.MapMaker.make(MapMaker.java:167) 
    ... 63 more 

什麼,我有我的fillArrayList方法做的是,UM通過檢查方法名稱和添加「」用了setString設定值這些值傳遞到一個ArrayList中。但它看起來像是在某種程度上處理該方法,因爲我正在使用'?'重新實現查詢。用相應的值替換(正常情況下帶有''和整數的字符串)。但是一旦服務器啓動,它會拋出另一組涉及h2的異常。

[2015-10-13 17:18:56,600] ERROR {org.carbon.registry.core.jdbc.dao.JDBCLogsDAO} - Failed to get logs. General error: "java.lang.IndexOutOfBoundsException: Index: 1, Size: 1" [50000-140] 
org.h2.jdbc.JdbcSQLException: General error: "java.lang.IndexOutOfBoundsException: Index: 1, Size: 1" [50000-140] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327) 
    at org.h2.message.DbException.get(DbException.java:156) 
    at org.h2.message.DbException.convert(DbException.java:279) 
    at org.h2.message.DbException.toSQLException(DbException.java:252) 
    at org.h2.message.TraceObject.logAndConvert(TraceObject.java:386) 
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:104) 
    at org.carbon.registry.core.jdbc.dao.JDBCLogsDAO.internalGetLogs(JDBCLogsDAO.java:427) 
    at org.carbon.registry.core.jdbc.dao.JDBCLogsDAO.getLogList(JDBCLogsDAO.java:317) 
    at org.carbon.registry.core.jdbc.EmbeddedRegistry.getLogs(EmbeddedRegistry.java:2332) 
    at org.carbon.registry.core.caching.CacheBackedRegistry.getLogs(CacheBackedRegistry.java:402) 
    at org.carbon.registry.core.session.UserRegistry.getLogsInternal(UserRegistry.java:1806) 
    at org.carbon.registry.core.session.UserRegistry.access$3600(UserRegistry.java:60) 
    at org.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1777) 
    at org.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1774) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at org.carbon.registry.core.session.UserRegistry.getLogs(UserRegistry.java:1774) 
    at org.carbon.registry.indexing.ResourceSubmitter.submitResource(ResourceSubmitter.java:119) 
    at org.carbon.registry.indexing.ResourceSubmitter.run(ResourceSubmitter.java:76) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 
    at java.util.ArrayList.rangeCheck(ArrayList.java:635) 
    at java.util.ArrayList.get(ArrayList.java:411) 
    at javaagent.JDBCPublisher.getArrayList(JDBCAgentPublisher.java:151) 
    at javaagent.JDBCPublisher.modifyOriginalQuery(JDBCAgentPublisher.java:351) 
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:84) 
    ... 19 more 
[2015-10-13 17:18:56,601] WARN {org.carbon.registry.indexing.ResourceSubmitter} - An error occurred while submitting resources for indexing 
org.carbon.registry.core.exceptions.RegistryException: Failed to get logs. General error: "java.lang.IndexOutOfBoundsException: Index: 1, Size: 1" [50000-140] 
    at org.carbon.registry.core.jdbc.dao.JDBCLogsDAO.internalGetLogs(JDBCLogsDAO.java:465) 
    at org.carbon.registry.core.jdbc.dao.JDBCLogsDAO.getLogList(JDBCLogsDAO.java:317) 
    at org.carbon.registry.core.jdbc.EmbeddedRegistry.getLogs(EmbeddedRegistry.java:2332) 
    at org.carbon.registry.core.caching.CacheBackedRegistry.getLogs(CacheBackedRegistry.java:402) 
    at org.carbon.registry.core.session.UserRegistry.getLogsInternal(UserRegistry.java:1806) 
    at org.carbon.registry.core.session.UserRegistry.access$3600(UserRegistry.java:60) 
    at org.wso2.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1777) 
    at org.carbon.registry.core.session.UserRegistry$37.run(UserRegistry.java:1774) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at org.carbon.registry.core.session.UserRegistry.getLogs(UserRegistry.java:1774) 
    at org.carbon.registry.indexing.ResourceSubmitter.submitResource(ResourceSubmitter.java:119) 
    at org.carbon.registry.indexing.ResourceSubmitter.run(ResourceSubmitter.java:76) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:178) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.h2.jdbc.JdbcSQLException: General error: "java.lang.IndexOutOfBoundsException: Index: 1, Size: 1" [50000-140] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:327) 
    at org.h2.message.DbException.get(DbException.java:156) 
    at org.h2.message.DbException.convert(DbException.java:279) 
    at org.h2.message.DbException.toSQLException(DbException.java:252) 
    at org.h2.message.TraceObject.logAndConvert(TraceObject.java:386) 
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:104) 
    at org.wso2.carbon.registry.core.jdbc.dao.JDBCLogsDAO.internalGetLogs(JDBCLogsDAO.java:427) 
    ... 18 more 
Caused by: java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 
    at java.util.ArrayList.rangeCheck(ArrayList.java:635) 
    at java.util.ArrayList.get(ArrayList.java:411) 
    at javaagent.JDBCPublisher.getArrayList(JDBCAgentPublisher.java:151) 
    at javaagent.JDBCPublisher.modifyOriginalQuery(JDBCAgentPublisher.java:351) 
    at org.h2.jdbc.JdbcPreparedStatement.executeQuery(JdbcPreparedStatement.java:84) 
    ... 19 more 

它拋出一堆IndexOutOfBoundExceptions反覆用正確分配SQL查詢。有什麼可以解決這個問題.....我該怎麼做才能糾正這個問題?

+0

基於我猜想由'的getStackTrace()返回的數組日誌'具有小於兩個條目,所以你不能檢索索引的值'[1]'。 – SubOptimal

+0

但是cannotCompileException的原因是什麼?我認爲在這一點出現問題導致了最後一個例外。 – udani

+0

請問您可以添加更多關於'javaagent.JDBCTransformer.injectSetVariableMethods(JDBCClassTransformer.java:212)'的信息和你在這裏傳遞的對象'injectSetVariableMethods(CtMethod方法)'。 – SubOptimal

回答

0

查找下面的精簡示例,該示例打印方法org.h2.jdbc.JdbcPreparedStatement.setString(int, String)的每個調用的值。

以下目錄結構和內容假定:

./instrumented/ 
h2-1.4.186.jar 
javassist-3.7.ga.jar 
SetStringDemo.java 

的例子執行

javac -cp javassist-3.7.ga.jar;h2-1.4.186.jar SetStringDemo.java 
java -cp .;instrumented/;javassist-3.7.ga.jar;h2-1.4.186.jar SetStringDemo 

輸出

instrument class org.h2.jdbc.JdbcPreparedStatement 
create test database and insert some rows   
idx: 2 value: 'name 0'       
idx: 2 value: 'name 1'       
idx: 2 value: 'name 2'       
idx: 2 value: 'name 3'       
idx: 2 value: 'name 4'       

所以問題是最有可能的方式,你儀器類。

用於本示例的代碼。

import java.nio.file.Files; 
import java.nio.file.Paths; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import javassist.ClassPool; 
import javassist.CtClass; 
import javassist.CtMethod; 

public class SetStringDemo { 

    // exception handling left out for the PoC 
    public static void main(String[] args) throws Exception { 

     if (Files.deleteIfExists(
       Paths.get("instrumented/org/h2/jdbc/JdbcPreparedStatement.class") 
     )) { 
      System.out.println("previously instrumented class removed"); 
     } 

     System.out.println("instrument class org.h2.jdbc.JdbcPreparedStatement"); 
     ClassPool pool = ClassPool.getDefault(); 
     CtClass clazz = pool.get("org.h2.jdbc.JdbcPreparedStatement"); 
     CtMethod method = clazz.getDeclaredMethod("setString"); 
     method.insertAt(1, 
       "System.out.println(\"idx: \" + $1 + \" value: '\" + $2 + \"'\");" 
     ); 
     clazz.writeFile("instrumented/"); 

     System.out.println("create test database and insert some rows"); 
     try (Connection conn = DriverManager.getConnection("jdbc:h2:mem:", "sa", "")) { 
      String createTable = "CREATE TABLE TEST_TABLE(ID INT, NAME VARCHAR(1024))"; 
      conn.createStatement().executeUpdate(createTable); 

      String insertSql = "INSERT INTO TEST_TABLE VALUES(?, ?)"; 
      try (PreparedStatement insertStmnt = conn.prepareStatement(insertSql)) { 
       for (int i = 0; i < 5; i++) { 
        insertStmnt.setInt(1, i); 
        insertStmnt.setString(2, "name " + i); 
        insertStmnt.executeUpdate(); 
       } 
      } 
     } 
    } 
} 
+0

但是這個文件夾是什麼? – udani

+0

@ransi它僅用於存儲插裝類的PoC。 1)儘可能簡化PoC,2)有可能檢查儀器是否像預期的那樣。我假設你正在使用代理來安排你的課程。這對Po​​C無關緊要。但會增加不必要的複雜性。 – SubOptimal

相關問題