Oracle ADF:日志文件报告 ADFContext 泄漏

Oracle ADF: Log file reports ADFContext Leak

我在生产应用程序日志文件中遇到如下重复消息:

<Jul 13, 2018, 11:33:45,489 AM CEST> <Error> 
<oracle.adf.share.ADFContext> <BEA-000000> <ADFContext leak detected.
oracle.adf.share.ADFContext.setAsCurrent(ADFContext.java:1717)
oracle.adf.share.ADFContext.createDefaultContext(ADFContext.java:1337)
oracle.adf.share.ADFContext.getCurrent(ADFContext.java:1311)
oracle.adf.share.ADFContext.get(ADFContext.java:1607)
oracle.adf.share.jndi.MDSBackingStore.getMDSSession(MDSBackingStore.java:421)
oracle.adf.share.jndi.MDSBackingStore.isReadOnlyMDSStore(MDSBackingStore.java:197)
oracle.adf.share.jndi.MDSBackingStore.<init>(MDSBackingStore.java:153)

这是一个在 JDeveloper 12.2.1.3.0 上开发的 ADF 应用程序

我试图搜索此错误,但我只能找到:

我会尝试修改日志级别,但我不确定。我无法弄清楚更高的日志级别如何解决问题。这会影响性能吗?

有人解决过这个问题或者有什么建议吗?

P.S.: 这是我的第一个问题。如果我必须改进问题,请告诉我,谢谢。

两点:
1) Oracle 注释 2321165.1 指的是显示 oracle.bi classes 的不同堆栈跟踪。这就是为什么说它是BI问题。在您的堆栈中,我看到 ADFContext 是从内部 ADF class oracle.adf.share.jndi.MDSBackingStore.getMDSSession 调用的,因此如果您在日志中只看到这些消息中的很少一部分,则可能会忽略它。
2) 设置更高的日志记录级别不会解决问题。 (如果以这种方式解决了任何问题,则意味着代码可能是错误的!)提高日志记录级别的推荐步骤只是获取完整的堆栈跟踪,以标识 ADF 上下文在何处实例化且未正确释放。一旦知道问题出在哪里,就需要采取进一步的措施。如果代码是您的应用程序的一部分,请修复您的代码。

我找到了解决办法,我想分享一下:

这个问题很可能是由于 AM 调用正在创建一个默认的 ADFContext 对象而没有正确处理。

我们需要显式创建和处理 ADFContext:

MyAMImpl myAm = null; 
ADFContext ctx = null; 
try{ 
    ctx = ADFContext.initADFContext(null, null, null, null); 
    myAm = (MyAMImpl) Configuration.createRootApplicationModule(MODULE_NAME, MODULE_CONF); 
    //execute a select in db 
} catch (Exception ex) { 
    log.severe("Error while using MyAM.", ex); 
} finally { 
    if (myAm != null) { Configuration.releaseRootApplicationModule(myAm, false); }
    ADFContext.resetADFContext(ctx);
}

因此,您应该确保在重置 ADF 上下文的 finally 子句中包含代码,即:

 } finally {
     ADFContext.resetADFContext(currentADFContext);
 }

根据我的发现,原因是当线程(创建 ADF 上下文时第一次调用时生成的线程)停止时 ADFContext 泄漏检测打印堆栈跟踪 运行。当线程结束时,如果上下文仍然可用,则将其作为泄漏进行管理并打印原始堆栈跟踪。 而且你应该注意不要犯我通过将该调用封装在

中而犯的错误
if (myAm != null)

因为它无法按预期调用 resetADFContext。