如何在不使用dataSource或GORM Hibernate相关的任何内容的情况下在Grails服务中创建类groovy.sql.Sql的实例?在我的Grails应用程序中,当我尝试创建一个Sql实例时,在我的Service类中,我得到一个异常:
Caused by: java.lang.ClassNotFoundException: org.postgresql.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java_lang_ClassLoader$loadClass$1.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
at com.tav.admin.DbService.copyFileToTable(DbService.groovy:87)
似乎是一个类加载问题。这是服务方法。
long copyFileToTable(String sql, FileReader fileReader) {
println("System Class Loader: ${ClassLoader.getSystemClassLoader().getClass().getName()}")
println("Groovy Class Loader: ${Thread.currentThread().getContextClassLoader().getClass().getName()}")
Thread.currentThread().getContextClassLoader().loadClass(driverClassName)
ClassLoader.getSystemClassLoader().loadClass(driverClassName) // Note throws exception here!
props = new Properties()
props.setProperty('user', username)
props.setProperty('password', password)
PgConnection copyOperationConnection = (PgConnection) Sql.newInstance(url, props, driverClassName)
CopyManager copyManager = new CopyManager(copyOperationConnection)
return copyManager.copyIn(sql, fileReader)
}
输出:
System Class Loader: sun.misc.Launcher$AppClassLoader
Groovy Class Loader: groovy.lang.GroovyClassLoader
PostgreSQL驱动程序已在DriverManager中注册。我可以在我的服务中使用注入的dataSource但是我需要创建与GORM Hibernate无关的数据库的新连接以使用驱动程序特定的功能(PostgreSQL CopyManager)。
在DriverManager.isDriverAllowed()
中Class.forName(driver.getClass().getName(), true, classLoader);
返回null。
版本信息:Grails 2.5.1,Java jdk1.7.0_79,Groovy 2.0.6
我已将问题缩小到下面的代码行:
ClassLoader.getSystemClassLoader().loadClass(driverClassName) // Note throws exception here!
似乎Groovy / Grails使用GroovyClassLoader加载JDBC驱动程序,但是当您尝试从DriverManager.getConnection()获取连接时,驱动程序管理器尝试使用System Class Loader加载JDBC驱动程序。系统类加载器似乎没有意识到Groovy类加载器已经加载了类。就像DriverManager和System Class加载器一样,远离Groovy加载的类。
答案 0 :(得分:1)
在我的情况下,我有相同的情况(使用没有GORM的Sql)但使用MySQL。
我在 resources.groovy :
声明了一个dataSource beanbeans{
"otherDataSource"(BasicDataSource) {
driverClassName = 'com.mysql.Driver'
username = 'xxx'
password = 'xxxx'
url = 'jdbc:blablabla'
}
}
并将其注入服务
class MyService{
def otherDataSource
void doIt(){
def sql = new Sql(otherDataSource)
}
}
答案 1 :(得分:0)
为了与PostgreSQL接口,您需要在类路径中有一个合适的驱动程序,如堆栈跟踪所示。
你需要包含一个依赖项或一个捆绑在jar中的外部库,它将为你提供一个实现`javax.sql。*'的包。接口