本文主要描述在ADF开发中如何应用ADF Logger帮助开发人员调试和诊断错误。
场景:
在ADF开发过程中,经常会遇到各种各样的错误,其中有些错误比较容易排查,但是有一些则相对比较难以发现错误根源,此时,经常会使用到日志来显示诊断信息以帮助发现错误。在Java应用中,可以通过创建Java Logger显示Java的诊断信息,在ADF中,即应用ADF Logger进行显示。
Java.util.logging JDK的说明文档中,描述了关于使用日志的四个目标:
1、由最终用户和系统管理员进行问题诊断,这由简单的常见问题日志组成,可在本地解决或跟踪这些问题,如资源不足、安全失败和简单的配置错误。
2、 由现场服务工程师进行问题诊断,现场服务工程师使用的日志信息可以相当复杂和冗长,远超过系统管理员的要求。通常,这样的信息需要特定子系统中的额外日志记录。
3、由开发组织进行问题诊断,在现场出现问题时,必须将捕获的日志信息返回到原开发团队以供诊断。此日志信息可能非常详细,并且相当费解。这样的信息可能包括对特定子系统进行内部执行的详细跟踪。
4、由开发人员进行问题诊断,Logging API 还可以用来帮助调试正在开发的应用程序。这可能包括由目标应用程序产生的日志信息,以及由低级别的库产生的日志信息。但是要注意,虽然这样使用非常合理,但是 Logging API 并不用于代替开发环境中已经存在的调试和解析工具 。
java.util.logging.level类中定义了一组可以用来控制日志输出的标准日志级别,按照严重程度由高到低依次为:
1、SERVER
2、WARNING
3、INFO
4、CONFIG
5、FINE
6、FINER
7、FINEST
具体说明参见文档(P892 b31973.pdf)
下面我们将为应用howtoapplyadflogger应用Adflogger,该应用完成了简单的浏览公司职位信息(Jobs)功能。
实现:
1、开启诊断日志,需要设置Java系统参数jbo.debugoutput值为console,在Jdeveloper中可以进行设置:双击打开Model项目,选择“Run/Debug/Profile”项,在“Run Configurations”中选中Default,点击“Edit”按钮,在Java Options中填入-Djbo.debugoutput=console,用于开启诊断日志,这个也是最简单的开启诊断日志的方法。
2、此时运行AppModule(AM),可以看到诊断日志已经在Jdeveloper中打印出来。
[322] *** Using bean introspection to lookup value :clientProxyInterfaceName [323] Replacing: null with: AppModule_JobsVO1PageDef [324] Resolving VO:AppModule.JobsVO1 for iterator binding:oracle_jbo_uicli_binding_JUIteratorBinding_0 [325] UIMessageBundle (language base) being initialized [326] DCUtil, RETURNING: [327] Tester startup time: 6 s. [328] INFO: No app _def_ in BindingContext for: AppModule [329] DCUtil, returning:oracle.jbo.uicli.binding.JUApplication, for AppModule [330] Replacing: null with: AppModule_JobsVO1_0PageDef [331] INFO: No app _def_ in BindingContext for: AppModule [332] DCUtil, returning:oracle.jbo.uicli.binding.JUApplication, for AppModule [333] INFO: No app _def_ in BindingContext for: PROJECT_GLOBAL_VARIABLES [334] INFO: mDCRefMap lookup failed. Does the cpx have a dataControlUsages 'dc' entry? PROJECT_GLOBAL_VARIABLES [335] Resolving VO:AppModule.JobsVO1 for iterator binding:oracle_jbo_uicli_binding_JUIteratorBinding_1 [336] DCUtil, RETURNING: [337] JobsVO1 ViewRowSetImpl.execute caused params to be "un"changed [338] Column count: 4 [339] ViewObject: JobsVO1 Created new QUERY statement [340] JobsVO1>#q computed SQLStmtBufLen: 144, actual=117, storing=147 [341] SELECT JobsEO.JOB_ID, JobsEO.JOB_TITLE, JobsEO.MIN_SALARY, JobsEO.MAX_SALARY FROM JOBS JobsEO [342] Bind params for ViewObject: JobsVO1 [343] **** refreshControl() for BindingContainer :AppModule_JobsVO1_0PageDef [344] *** DCDataControl.sync() called from :DCBindingContainer.refresh |
3、在完成了前面的设置以后,就 可以使用业务组件浏览器来进行诊断和调试了,例如,我们为JobsEO生成对应的实现类JobsEOImpl.java,在其中添加如下代码:
private static ADFLogger logger = ADFLogger.createADFLogger(JobsEOImpl.class); /** * This is the default constructor (do not remove). */ public JobsEOImpl() { //Modified by Eleven.Xu, 2008.1.8 logger.info("JobsEOImpl AdfLogger Test!"); } |
4、此时再次运行业务组件浏览器,发现刚才修改的代码中添加的日志已经被打印出来。
[335] Resolving VO:AppModule.JobsVO1 for iterator binding:oracle_jbo_uicli_binding_JUIteratorBinding_1 [336] DCUtil, RETURNING: [337] JobsVO1 ViewRowSetImpl.execute caused params to be "un"changed [338] Column count: 4 [339] ViewObject: JobsVO1 Created new QUERY statement [340] JobsVO1>#q computed SQLStmtBufLen: 144, actual=117, storing=147 [341] SELECT JobsEO.JOB_ID, JobsEO.JOB_TITLE, JobsEO.MIN_SALARY, JobsEO.MAX_SALARY FROM JOBS JobsEO [342] Bind params for ViewObject: JobsVO1 2009-1-8 14:13:21 howto.adflogger.model.entities.JobsEOImpl 信息: JobsEOImpl AdfLogger Test! |
5、完成了对于Model项目的设置,为在应用运行时打印出必要的诊断日志,接下来将继续对配置文件和ViewController项目进行一些必要的设置,在设置前重新启动服务器并运行Main.jspx页面,没有诊断日志被打印。
严重: JSF1030: The specified InjectionProvider implementation 'com.bea.faces.WeblogicInjectionProvider' cannot be loaded. Application Deployed Successfully. Elapsed time for deployment: 30 seconds ---- Deployment finished. ---- Jan 8, 2009 9:28:40 AM Run startup time: 32125 ms. [Application howtoapplyadflogger deployed to Server Instance DefaultServer] Target URL -- http://127.0.0.1:7101/howtoapplyadflogger-ViewController-context-root/faces/Main.jspx 警告: ADFc: 用 'oracle.adfinternal.controller.application.model.JSFDataBindingLifecycleContextBuilder' 替换 ADF 页生命周期实施。 信息: ADFc: BindingContext 存在, 并且将 ADFm API 用于 DataControlFrames。 信息: ADFc: 启用了对 MDS 元数据资源的控制器高速缓存。 信息: ADFc: 从 '/WEB-INF/adfc-config.xml' 加载引导元数据。 |
6、修改logging.xml文件,该文件的位置位于:
(1)如果设置了JDEV_HOME,则在该环境变量对应路径下的system
(2)如果没有设施JDEV_HOME,则在Jdeveloper安装目录下的system/system
查看该文件:
红色部分name为空,表示应用于所有package,其日志显示级别为WARNING,则可以显示WARNING或比WARNING更高级的日志信息,这里是Oracle的建议方式,通过这种方式过滤一些低级别的日志信息,保留该默认设置,如果需要对某些package进行更低级别的日志打印,则需要在蓝色部分添加对应信息,例:我们添加打印了oracle和howto两个package的日志信息,级别都为INFO。
7、重新启动服务器并运行页面,发现还是不能打印出诊断信息,还需要对于ViewController项目进行简单的设置:双击打开ViewController项目,选择“Run/Debug/Profile”项,在“Run Configurations”中选中Default,点击“Edit”按钮,在Java Options中填入-Djbo.debugoutput=console。
8、为查看View层中的日志,在Main.jspx页面添加新按钮,并在对应的Backing Scope的Managed Bean中该Button的事件方法中打印出了日志信息,代码如下:
public String loggerTest() { logger.info("Managed Bean(Button) Logger Test!"); logger.fine("Fine Level Managed Bean(Button) Logger Test!"); return null; } |
9、重新启动服务器并运行Main.jspx页面,查看日志显示情况。
补充:在Jdeveloper中有可能设置了日志显示级别为FINE或者FINEST后,却仍然不能显示出对应级别的日志信息, 是由于在Jdeveloper使用的JRE的lib中的logging.property文件中规定了默认日志显示的级别为INFO(.level= INFO),可以根据情况进行调整,以显示对应级别的日志信息,必须注意的是,伴随日志显示级别的降低,日志打印内容越来越多,由于Java需要大量操作IO,必然导致运行速度变慢,因此,一般情况下,只需将其中的级别设置为INFO。
[366] **** refreshControl() for BindingContainer :howto_adflogger_view_MainPageDef [367] valiateToken:Decompressed BC state:BCST:=0%V%=NJobsVO1Iterator=-D-, [368] DCUtil, returning:oracle.adf.model.binding.DCParameter, for AppModuleDataControl [369] (oracle.adf.model.bc4j.DataControlFactoryImpl.SyncMode = Immediate [370] Reusing a cached session application module instance [371] **** PoolMessage REQ ATTACH LWS [372] Invoke refresh for :JobsVO1Iterator [373] Executing and syncing on IteratorBinding.refresh from :JobsVO1Iterator [374] Resolving VO:JobsVO1 for iterator binding:JobsVO1Iterator 2009-1-8 14:10:55 howto.adflogger.view.backing.Main loggerTest 信息: Managed Bean(Button) Logger Test! |
相关代码请查看:
0 评论:
发表评论