[SalesForce] ‘System.LimitException: Maximum stack depth reached: 1001’ Error message

What is the meaning of the error message:

System.LimitException: Maximum stack depth reached: 1001

I am trying below code, and on previewing the page from 'Developer Console', this error appears.

VF Page:

<apex:page controller="ObjectDetails">
    <apex:pageBlock title="Object Details in this environment" id="oD_list">
        <apex:pageBlockTable value="{!objectdetail}" var="o">
            <apex:column value="{!o.objectname}"/apex:column>
            <apex:column value="{!o.apiname}/apex:column>
        <apex:pageBlockTable>
    <apex:pageBlock>
<apex:page>

Apex Class:

public class ObjectDetails {

    String objectName, apiName;
    List<ObjectDetails> ODList=new List<ObjectDetails>();
    ObjectDetails odObl=new ObjectDetails();
    public List<ObjectDetails> getObjectDetail(){
         for(Schema.SObjectType sO: Schema.getGlobalDescribe().values()){
            Schema.DescribeSObjectResult oRE = sO.getDescribe();
            odObl.objectName=oRE.getLabel();
            odObl.apiName=oRE.getName();
            ODList.add(odObl);
        }
        return ODList;
    }
    public String getobjectName(){
        return objectName;
    }
    public String getapiName(){
        return objectName;
    }
}

Best Answer

When method is called space is reserved on the stack for the arguments to the method and the local variables inside the method so part of a block of memory (of limited size) is used. And methods can call other methods.

When that chain of method calls gets very long, it is most often because of a programming error where a method (or chain of methods) calls itself resulting in a never-ending cycle that will never return a result. Salesforce detects and throws the error you see to alert you of that situation.

Right now I can't see the cause of such a never-ending cycle in the code you have posted.

One mistake I do see is that you are adding the same instance of odObl many times to the list. Also the ODList is best moved so:

public class ObjectDetails {

    String objectName, apiName;

    public List<ObjectDetails> getObjectDetail() {

        // Better to not have this in every instance of ObjectDetails
        List<ObjectDetails> ODList=new List<ObjectDetails>();

        for(Schema.SObjectType sO: Schema.getGlobalDescribe().values()){
            Schema.DescribeSObjectResult oRE = sO.getDescribe();

            // Moved this to inside the loop
            ObjectDetails odObl=new ObjectDetails();

            odObl.objectName=oRE.getLabel();
            odObl.apiName=oRE.getName();
            ODList.add(odObl);
        }

        return ODList;
    }

    public String getobjectName() {
        return objectName;
    }

    public String getapiName() {
        // Changed this too
        return apiName;
    }
}