Search code examples
oracle-databaseoracle-adfweblogic12c

Oracle ADF: Log file reports ADFContext Leak


I'm facing repetitive messages like following on production application log file:

<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)

It's an ADF application developed on JDeveloper 12.2.1.3.0

I've tried to search this error but all I could find was:

  • a bug issue (on Oracle Support, Doc ID 2321165.1) with solution saying that "these messages can normally be ignored" and that it was a BI bug problem, ADF just reporting that. (But I'm not using BI on this project)

  • another site saying to modify logging level from Managed Server Log Configuration on Weblogic for class "oracle.adf.share.ADFContext" from INFO to FINEST. There's also this question here on stakoverflow, but I cannot insert any comment (need 50 point reputation) and I'm not sure it's the same problem.

I'd try to modify log level, but I'm not sure of this. I can't figure out how an higher log level can solve the problem. And will this impact on performance?

Someone solved this problem before or has suggestions?

P.S.: This is my first question here. Let me know if I have to improve the question, thanks.


Solution

  • I've found out a solution and I want to share:

    The problem is most likely caused by the fact the AM call is creating a default ADFContext object and it is not disposed off properly.

    We need to explicitly create and dispose the 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);
    }
    

    So, you should be sure to include the code in the finally clause that resets the ADF context, ie:

     } finally {
         ADFContext.resetADFContext(currentADFContext);
     }
    

    Reason, for what I've found, is ADFContext leak detection print stack trace when the thread (the one generated when ADF Context was created making first call) stops running. When thread is ended, if context is still available it is managed as a leak and the original stack trace is printed. And you should pay attention not to do the error I've made by incapsulating that call inside an

    if (myAm != null)
    

    because it could not call resetADFContext as expected.