之前的一篇文章《业务事件之Java Rule Function》简单介绍了Java Rule Function的使用。在Oracle Workflow 2.6.x体系中,针对Function Activity的External Java也是非常有用的,同样的,也提供了接口以供编写应用程序。这两种方式,对于在应用层和异构系统交互或者处理其他一些PL/SQL无法完成的事务时,是绝对的利器。
在利用业务事件做实际应用时,根据经验,需要注意下面几点:
不要对JDBC Connection做close或release之类的操作。
Java Deferred Agent Listener一旦起来后,如果某个Java Rule Funtion中做了关闭数据库链接的操作,则会导致相应的队列(wf_java_deferred)中数据无法被处理,你甚至无法再单独重启该listener。
当然,你依然可以通过重启 Workflow Agent Listener Service 来使Java Deferred Agent Listener重新运作。
分步诊断
只有了解业务事件的整体架构后,才能更有效的找到问题真实症结所在。这里主要有三部分需要留意:
- 数据首先是被插入queue,此时可以使用预置文件FND: Debug Log Enabled和FND: Debug Log Level打开日志记录。Workflow用的是标准的FND_LOG包来记录日志的。
- 在调用Java程序时,系统首先去检查缓存,如果缓存中已经存在该对象,则不再从硬盘中读取。因而如果Java程序被调用过又有更新的话,需要重启应用才能生效。如果不重启,一些异常信息可能并不完整,比如NoClassDefFoundError,可能并不提供未找到的类名。
- 针对Java Deferred Agent Listener有单独的日志记录,需要进workflow manager中设置log level。诊断完毕后千万记得重新将log level设置回原先的值。Java程序中的log也会记录到这里。
标准的Log代码:
private void log(String s, int i) {
AppsLog appslog = (AppsLog) wfCtx.getLog();
if (appslog.isEnabled(i))
appslog.write(this, s, i);
}
Event参数传递
虽然subscription也可以传递参数,但是它的参数格式很别扭:var1=val1 var2=val2,多个参数以空格间隔,组成一个字符串传递过来。还要自己写程序来解析,比较麻烦。而且关键是,这些参数是静态定义的,无法在raise event时动态创建。所以Java中一般使用event中传递过来的参数。
在Oracle EBS系统中,DB和应用使用两套不同的JVM。如果在DB层写Java Procedure,若是需要第三方库,则要通过loadjava来导入DB。而应用层则相对简单,直接上传到$JAVA_TOP相应目录下即可。一般来讲,此类处理异构系统之间的程序,是不会放在DB层来实现的。
此外,在定义Subscription时,若没有特殊需求,将Rule Data设置为Key会比Message更有效。