JBoss JDBC驅動報錯問題分析與解決
問題描述:
JBoss JDBC驅動時,第一次建立如果庫連接會拋出類似于下面的異常
21:21:36,666 WARN [JBossManagedConnectionPool] Throwable while attempting to get a new connection: null
org.jboss.resource.JBossResourceException: Could not create connection; - nested throwable: (org.jboss.resource.JBossResourceException: Apparently wrong driver class specified for URL: class: oracle.jdbc.driver.OracleDriver, url: jdbc:oracle:thin:@ 10.0.32 .25:1521:sid)
at org.jboss.resource.adapter.jdbc.local.LocalManagedConnectionFactory.createManagedConnection(LocalManagedConnectionFactory.java:179)
at org.jboss.resource.connectionmanager.InternalManagedConnectionPool.createConnectionEventListener(InternalManagedConnectionPool.java:565)
但在第二次取得數據庫連接時卻是正常的。
解決方法:
將JBoss JDBC驅動拷貝到jboss_server_home/lib目錄下。這個方法對于每一個jboss環境都需要進行這樣的拷貝,比較麻煩。
問題分析:
出現這個問題的JBoss服務器配置文件jboss_server_home/deploy/jbossweb-tomcat55.sar/META-INF/jboss-service.xml里的UseJBossWebLoader配置項應該都是配置成為false的,即使用的并不是JBoss共享扁平的ClasssLoader并且jboss_server_home/lib不包含JBoss JDBC驅動。下面我們來分析造成這個問題的具體原因。
首先我們來了解一下JBoss JDBC驅動的管理。JBoss JDBC驅動程序在載入的時候都會通過java.sql.DriverManager.registerDriver(Driver)方法將自身注冊到驅動管理器中。在注冊后我們就可以通過DriverManager.getDriver(String url)方法取得能夠處理傳入的數據庫url的驅動程序,或者通過DriverManager.getConnection(String url, String user, String password)方法取得url對應驅動的連接。但在這里有一個問題需要我們注意,在取得連接或者驅動的時候,它需要從已注冊的驅動里選擇合適的驅動程序出來。這個合適的驅動總結出來有兩條
一是當前調用getDriver或getConnect方法的類的ClassLoader能夠載入相應的JBoss JDBC驅動程序,并且載入的JBoss JDBC驅動程序類要和已注冊的驅動程序類相等,調用getDriver或getConnect方法的類ClassLoader通過本地方法DriverManager.getCallerClassLoader()獲得,它得到調用類的ClassLoader。
二是對于符合前面條件的驅動,還需要判斷當前這個驅動能不能處理連接url,如果不符合,則從注冊的驅動里查找下一次驅動,如果滿足,則使用這個驅動來創建連接。
【編輯推薦】