EMC Developer Network

Detecting Orphaned Objects in DFC

April 2005

Abstract

In a previous tip we discussed enabling DFC session diagnostics to detect session leaks. In this tip we extend upon that tip and discuss orphaned objects and their detection.

Software Environment

FeatureTested on
Operating SystemWindows 2000 Server SP4
CompilerSun JDK 1.4.2_05
RuntimeSun JRE 1.4.2_05
Content Server5.3
DFC5.3
WDK5.3
Webtop5.3

Orphaned Objects

Simple Example

Orphaned objects are objects obtained from a session that has already been released back to the DFC session manager. Support for detection of orphaned objects was added in DFC 5.3. Orphaned objects can be detected by enabling DFC session diagnostics . Lets see a simple example of an orphaned object.


        try
        {
            
            ....
            IDfSessionManager sessMgr = lm.getSessionManager();
1>            IDfSession sess = sessMgr.getSession("wdk53no");
            
2>            IDfSysObject sObj = (IDfSysObject) sess.getObjectByPath("/Templates");
            
3>            sessMgr.release(sess);
            
              //this line will throw an exception because
              //session attached to sObj has already been released.
4>            String objName = sObj.getObjectName();
            
        }
        catch(DfException dfex)
        {
            dfex.printStackTrace();
        }               

Line 2 gets an instance of a sysobject to perform some operations on it. The sysobject gets associated with the 'sess' using which it was obtained. Line 3 releases this 'sess' back to the session manager. Now, line 4 tries to perform some operation on the sysobject obtained earlier. However, the 'sess' attached to this object has been released in line 3 thus making the sysobject an orphaned object. Due to this, Line 4 will thow a DFC_BOF_SESSION_ALREADY_RELEASED exception. Here is what the stack trace looks like. The last line of the stack trace will tell you the line number where an attempt was made to access an orphaned object.

12:01:04,453 ERROR [main] com.documentum.fc.client.DfSessionLeakChecker - 
[DFC_BOF_SESSION_ALREADY_RELEASED] An attempt of using the already released session.
com.documentum.fc.client.DfSessionAlreadyReleasedException: [DFC_BOF_SESSION_ALREADY_RELEASED] 
An attempt of using the already released session.
	at com.documentum.fc.client.DfSessionLeakChecker.checkForReleasedSession(DfSessionManager.java:1263)
	at com.documentum.fc.client.DfDisposableSession$1.check(DfDisposableSession.java:1029)
	at com.documentum.fc.client.DfFolder___PROXY___PROXY_X.getObjectName(DfFolder___PROXY___PROXY_X.java)
	at scratchpad.TestOrphanedObject.main(TestOrphanedObject.java:38)
Caused by: com.documentum.fc.client.DfSessionAlreadyReleasedException: [DFC_BOF_SESSION_ALREADY_RELEASED]
An attempt of using the already released session.
	at com.documentum.devprog.scratchpad.TestOrphanedObject.main(TestOrphanedObject.java:34)

Threaded Example

The above example was quite simple. In real life, orphaned objects might occur in multi-threaded applications. Here is an example that involves more than one thread. In this the main thread obtains the sysobject (1) and then gives it to a worker thread (2) that then does some processing(4) on it. However, the main thread also releases the session(5) after starting the worker thread. The problem is that by the time the worker thread starts to use the sysobject the main thread has already released the session to which the sysobject was attached. This will throw a DFC_BOF_SESSION_ALREADY_RELEASED exception.

Note:The sleep time (3) in the worker thread has been introduced to simulate a sense of randomness between usage of the sysobject and the release of the attached session.

public class TestThreadedOrphanedObject
{

    public static void main(String[] args)
    {
        
        try
        {
            LoginManager lm = new LoginManager("tuser8","n0lif3","wdk53no");
            
            IDfSessionManager sessMgr = lm.getSessionManager();
            IDfSession sess = sessMgr.getSession("wdk53no");
            
1>            IDfSysObject sObj = (IDfSysObject) sess.getObjectByPath("/Templates");
            
            //main thread starts off a new thread to do processing on
            //sysobject
2>            Worker tstThr = new Worker(sObj,4000);
            Thread workerThr = new Thread(tstThr);
            workerThr.start();
            
            //main thread releases the session to which the sysobject is 
            //attached. this results in the object in the worker thread getting
            //orphaned
5>            sessMgr.release(sess);
                        
            
        }
        catch(DfException dfex)
        {
            dfex.printStackTrace();
        }               
    
    }
    
    
    static class Worker implements Runnable
    {
        IDfSysObject sObj = null;
        long sleepTime = 100;
        
        Worker(IDfSysObject sObj,long sleepTime)
        {
            this.sObj = sObj;
            this.sleepTime = sleepTime;
        }
        
        public void run()
        {
            try
            {
3>                Thread.sleep(sleepTime);
4>                String name = sObj.getObjectName();
                
                
            }
            catch(InterruptedException ie)
            {
                //
            }
            catch(DfException dfe)
            {
                dfe.printStackTrace();
            }
            
        }
        
    }
}

To avoid a scenario like the above, it is better to not pass IDfSysObjects between threads. Instead an IDfId should be passed and the sysobject obtained within the thread using the IDfSession#getObjectXyz(...) methods. Also, an IDfSession instance should not be shared amongst threads. Instead an IDfSessionManager instance should be shared amongst threads and each thread should obtain an IDfSession using IDfSessionManager#getSession().

Bugs or Comments

If you find bugs or issues with the component/article, please contact developer_program@documentum.com with a short description of the issue, steps to reproduce it and the relevant software environment.