Я пишу некоторые скрипты Groovy для анализа моих банковских выписок и загрузки их в дерби db. Я застрял, пытаясь получить соединение с моим дерби db от Groovy. Я использую documentation found here. Я пытаюсь добавить дерби к пути класса динамически, но он не работает.Использование Derby из Groovy
import java.sql.*
def env = System.getenv()
def sql
try{
DriverManager.getConnection('jdbc:derby:;shutdown=true')
}
catch (SQLException se){
def derbyURL = new File("${env['JAVA_HOME']}/db/lib/derby.jar")
println "Loading derby: ${derbyURL.exists()}"
this.class.classLoader.rootLoader.addURL(derbyURL.toURL())
def sqlClass = Thread.currentThread().contextClassLoader.loadClass('groovy.sql.Sql')
sql = sqlClass."newInstance"("jdbc:derby:cliffdb;")
}
От этого я получаю
Loading derby: true
Exception thrown
Feb 01, 2014 10:47:38 AM org.codehaus.groovy.runtime.StackTraceUtils sanitize
WARNING: Sanitizing stacktrace:
java.sql.SQLException: No suitable driver found for jdbc:derby:cliffdb;
at java.sql.DriverManager.getConnection(DriverManager.java:596)
at java.sql.DriverManager.getConnection(DriverManager.java:233)
at groovy.sql.Sql.newInstance(Sql.java:232)
at groovy.sql.Sql$newInstance.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at BankStatementReader.run(BankStatementReader.groovy:13)
Я пробовал все варианты Sql.newInstance от прямого вызова его загрузки класса Sql из корневого класса загрузчика в настоящее время погрузки класса Sql из текущий загрузчик классов контекста потока. Что мне не хватает, и почему это не работает, когда на самом деле присутствует Derby jar?
** Update **
Я просто переехал мой Sql код загрузки в отдельный класс отзывной и превратили свой оригинальный сценарий в полном проекте IntelliJ Groovy. Код ниже работает благодаря ответу, указанному в комментариях ниже!
package com.craig.banking.db
import java.sql.DriverManager
import java.sql.SQLException
/**
* Created by clifton on 2/2/14.
*/
public class DBSqlProvider {
static groovy.sql.Sql sql;
def dbProperties = new Properties()
def env = System.getenv()
DBSqlProvider() {
dbProperties.load(getClass().getResourceAsStream("/db.properties"))
}
def findSql() {
try{
DriverManager.getConnection(dbProperties.dbURL)
}
catch (SQLException se){
def derbyURL = new File("${env['JAVA_HOME']}/db/lib/derby.jar")
println "Loading derby: ${derbyURL}"
def rootLoader = this.class.classLoader.rootLoader
rootLoader.addURL(derbyURL.toURL())
Class.forName('org.apache.derby.jdbc.EmbeddedDriver')
def sqlClass = rootLoader.loadClass('groovy.sql.Sql')
sql = sqlClass."newInstance"(dbProperties.dbURL)
}
}
def getSql() {
findSql()
if (null == sql) {
sql = groovy.sql.Sql.newInstance(dbProperties.dbURL)
}
return sql
}
}
Это работает, если вы запускаете скрипт с помощью '-cp derby.jar: .' вместо того, чтобы пытаться манипулировать загрузчиком системного класса в скрипте? –
Да, но я был слишком ленив, чтобы выйти из своей интерактивной консоли, обновить путь к классу и начать заново. Меня больше интересует, почему динамическая часть работает не так, как ожидалось. – Cliff
После динамической настройки пути к классам вы попытались загрузить класс org.apache.derby.jdbc.EmbeddedDriver? Я думаю, что это внутренне вызовет DriverManager.registerDriver, что дает DriverManager связь между схемой jdbc: derby: url и драйвером JDBC EmbeddedDriver. –