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 应用程序
我试图搜索此错误,但我只能找到:
一个错误问题(在 Oracle 支持上,文档 ID 2321165.1),解决方案说 "these messages can normally be ignored" 并且这是一个 BI 错误问题,ADF 只是报告了这一点。 (但我没有在这个项目上使用 BI)
另一个站点说要从 class "oracle.adf.share.ADFContext" Weblogic 上的托管服务器日志配置修改日志记录级别,从 INFO 到 FINEST。在 stakoverflow 上也有 this question,但我无法插入任何评论(需要 50 点声望)而且我不确定这是不是同样的问题。
我会尝试修改日志级别,但我不确定。我无法弄清楚更高的日志级别如何解决问题。这会影响性能吗?
有人解决过这个问题或者有什么建议吗?
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。
我在生产应用程序日志文件中遇到如下重复消息:
<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 应用程序
我试图搜索此错误,但我只能找到:
一个错误问题(在 Oracle 支持上,文档 ID 2321165.1),解决方案说 "these messages can normally be ignored" 并且这是一个 BI 错误问题,ADF 只是报告了这一点。 (但我没有在这个项目上使用 BI)
另一个站点说要从 class "oracle.adf.share.ADFContext" Weblogic 上的托管服务器日志配置修改日志记录级别,从 INFO 到 FINEST。在 stakoverflow 上也有 this question,但我无法插入任何评论(需要 50 点声望)而且我不确定这是不是同样的问题。
我会尝试修改日志级别,但我不确定。我无法弄清楚更高的日志级别如何解决问题。这会影响性能吗?
有人解决过这个问题或者有什么建议吗?
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。