You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Groovy调用Oracle存储过程时遭遇groovy.sql.Sql类加载错误

解决Groovy调用Oracle存储过程时“Unable to load class groovy.sql.Sql”的问题

我遇到过类似的问题,结合你的场景和错误堆栈来看,这个编译错误本质上不是找不到groovy.sql.Sql类本身,而是编译器解析Sql.INTEGER、Sql.VARCHAR这些静态常量时,依赖的JDBC核心类(比如java.sql.SQLException)在编译路径中缺失或者加载异常——尤其是你用Groovy 2.4.13搭配JDK9时,JDK9的模块化特性可能会影响类的可见性。

先回顾你的场景:注释的SELECT查询能正常运行,但带OUT参数类型的query.call调用触发编译错误,移除[Sql.INTEGER, Sql.VARCHAR]后编译正常,临时用PL/SQL块的方式可以绕开问题,但你想要更优雅的原生Groovy写法。

优雅的解决方案:正确使用Groovy Sql的OUT参数标记

Groovy的Sql类提供了原生的OUT参数支持,不需要手写PL/SQL块,你可以通过Sql.OUT()方法明确标记参数方向和类型,调整后的代码如下:

import groovy.sql.Sql
import java.util.logging.*

Logger.getLogger('groovy.sql').level = Level.ALL
def dbUser = 'YOU'
def dbPassword = 'WILL'
def dbDriver = 'oracle.jdbc.driver.OracleDriver'
def dbURL = 'NEVER:KNOW'

def query = Sql.newInstance(dbURL, dbUser, dbPassword, dbDriver)
def affiliateNumber = 18
def depositIdentifier = 55
def depositType = "00"
def depositAmount = 18.49
def depositCommunication = 135453
def depositDate = new Date().toTimestamp()
def criterium = 0

// 定义接收OUT参数的变量
def returnCode
def errorMessage

// 正确的存储过程调用方式:用Sql.OUT标记输出参数
query.call("{ CALL PAC_GCA_IMP_AUTO_2.IMP_AUTO(?, ?, ?, ?, ?, ?, ?, ?, ?) }", 
           [
               affiliateNumber, 
               depositIdentifier, 
               depositType, 
               depositAmount, 
               depositCommunication, 
               depositDate, 
               criterium, 
               Sql.OUT(Sql.INTEGER),  // 标记第一个OUT参数的类型
               Sql.OUT(Sql.VARCHAR)   // 标记第二个OUT参数的类型
           ]) { code, msg ->
    // 回调中接收OUT参数的值
    returnCode = code
    errorMessage = msg
}

println "返回码: ${returnCode}, 错误信息: ${errorMessage}"
query.close()

关键修复点说明

  1. 参数方向标记:使用Sql.OUT(type)明确告诉Groovy哪些是输出参数,替代之前直接传递类型数组的写法,这种方式更清晰,也能避免编译器解析静态常量时的类加载问题。
  2. 依赖检查:确保你的classpath中包含:
    • groovy-sql-2.4.13.jar(或完整的groovy-all-2.4.13.jar)
    • 对应JDK版本的Oracle JDBC驱动(比如JDK8用ojdbc7.jar/ojdbc8.jar,JDK9注意驱动兼容性)
  3. JDK9兼容性调整:如果坚持用JDK9,需要在编译/运行时添加--add-modules java.sql参数,确保JDBC模块被正确加载(Groovy 2.4.x对JDK9的支持有限,优先推荐用JDK8更稳定)。

为什么临时方案能运行?

你用PL/SQL块的写法绕开了直接引用groovy.sql.Sql的静态类型常量,编译器不需要解析这些依赖JDBC类的常量,所以不会触发类加载错误,但这种写法失去了Groovy Sql的简洁性,原生写法显然更符合Groovy的风格。

内容的提问来源于stack exchange,提问作者Grechka Vassili

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:50:48