报错如下:
weaver.conn.util.ProcChecker
java.lang.ClassNotFoundException: com.weaver.procedure.test.Test_20220808 (in EnvironmentClassLoader[web-app:production/webapp/default/ROOT])
at com.caucho.loader.DynamicClassLoader.loadClass(DynamicClassLoader.java:1559)
at com.caucho.loader.DynamicClassLoader.loadClass(DynamicClassLoader.java:1529)
存储过程却能够正常执行。
看下这个RecordSet.executeProc方法
public boolean executeProc(String var1, List<String> var2, String var3) {
if (!"".equals(var1) && MonitorSqlUtil.getInstance().isIntercept(var1)) {
(new BaseBean()).writeLog(var1 + "此sql不符合性能要求,已被拦截!");
return false;
} else {
var1 = var1.trim();
ProcChecker var4 = new ProcChecker(new ProcParamStore(var1, var3, this, this.args, true));
if (var4.hasClass()) {
try {
var4.executeProc();
this.bSuccess = true;
} catch (Exception var39) {
this.setExceptionMsg(var39.getMessage());
this.bSuccess = false;
this.writeLog(var39);
}
return this.bSuccess;
} else {
this.sqlTmp = var1;
this.setExceptionMsg("");
long var5 = 0L;
long var7 = 0L;
if (StringUtil.isEmpty(var1)) {
this.setExceptionMsg("Query statement or procedure name is empty!");
return false;
} else {
....以下省略
}
再看了下一下,这个 weaver.conn.util.ProcChecker 类
public class ProcChecker extends BaseBean {
private static final Map<String, Constructor<?>> constructMap = new ConcurrentHashMap();
private static final String PREFIX_PACKAGE = "com.weaver.procedure.";
private boolean hasClass = true;
private DBProcedureInterfaceWrapper dbpWrapper;
private static final Lock lock = new ReentrantLock();
public ProcChecker(ProcParamStore var1) {
String var2 = var1.getProcName();
if (!StringUtil.isEmpty(var2)) {
var2 = var2.toLowerCase();
Constructor var3 = (Constructor)constructMap.get(var2);
try {
if (var3 == null) {
lock.lock();
try {
if ((var3 = (Constructor)constructMap.get(var2)) == null) {
String var4 = this.getClassPath(var2);
Class var5 = Class.forName(var4);
if (var5.isAnnotationPresent(PendingProc.class)) {
this.writeLog("the related procedure is not completed yet : " + var2);
this.hasClass = false;
return;
}
var3 = var5.getConstructor(ProcParamStore.class);
constructMap.put(var2, var3);
}
} finally {
lock.unlock();
}
}
this.dbpWrapper = new DBProcedureInterfaceWrapper((DBProcedureMethodInterface)var3.newInstance(var1));
} catch (Exception var10) {
this.writeLog(String.format("info: proc %s-----%s\n", var2, var10.getMessage()));
this.hasClass = false;
this.writeLog("no related class refers to the procedure : " + var2);
}
}
}
....以下省略
}
大概了解,在执行存储过程 ProcChecker 这个类构造方法,执行到这个导致错误出现
Class var5 = Class.forName(var4),抛出:java.lang.ClassNotFoundException: com.weaver.procedure.
也就是说E9 中调用存储过程,每个存储过程对应下 com.weaver.procedure 都有具体的实现类。
以系统的存储过程为例:
Base_freefield_select
CREATE OR REPLACE PROCEDURE Base_FreeField_Select(tablename_1 varchar2,
flag out integer,
msg out varchar2,
thecursor IN OUT cursor_define.weavercursor) AS
begin
open thecursor for
SELECT * FROM Base_FreeField WHERE tablename = tablename_1;
end;
package com.weaver.procedure.base;
import weaver.conn.DBProcedureSimpleInterface;
import weaver.conn.util.ProcParamStore;
public class Base_freefield_select extends DBProcedureSimpleInterface {
private Object[] params;
public Base_freefield_select(ProcParamStore var1) {
super(var1);
this.params = var1.getParams();
}
public void executeProc() throws Exception {
this.executeQuery("SELECT * FROM Base_FreeField WHERE tablename= ?", new Object[]{this.params[0]});
}
}
结论如下:
1.解决报错问题,对应的存储过程,对应存储过程类继承 DBProcedureSimpleInterface ,重写这个executeProc 方法
2.使用executeProc2 ,支持标准调用存储过程,去掉注册参数flag 、msg。
executeProc 和 executeProc2 调用相同,参数列表1.存储过程,2. 参数,多个使用Util.getSeparator() 分开,3.数据源名称,如果是OA的数据源,为空即可
3.不用专注这个错误,进去是打印一个日志,不会影响到存储过程执行
4.现在的业务逻辑不推荐使用存储过程来实现,存储过程难以调试及扩展(阿里巴巴开发手册中提到这点)