0

After creating a Managed Package, I am facing issue with Class in following line:

Schema.DescribeSObjectResult objResult = GlobalDescribeMap.get(objectName).getDescribe();

Error message:

System.NullPointerException: Attempt to de-reference a null object

Class:

global class AnalyzeObjectBatch implements Database.Batchable<sObject>,Database.Stateful {

    global string objectName;
    global string objForAnalysisID;
    Object_Analysis__c objForAnalysis ;
    List<Field_Analysis__c> fieldAnalysisList ;
    List<Field_Analysis__c> fieldAnalysisListToDel ;
    Map<string,Field_Analysis__c> fieldAnalysisMap ;
    Map<string,Field_Analysis__c> fieldAnalysisOldMap ;
    integer recordCount = 0;
    //Schema.DescribeSObjectResult objResult ;
    Set<string> fieldSet ;
    global Map<String, Schema.SObjectType> GlobalDescribeMap ;

    global AnalyzeObjectBatch(string objAnalysisID){
        objForAnalysisID = objAnalysisID;
        System.debug('---------05'+ objForAnalysisID);
        objForAnalysis = [select Name,Record_Count__c,Object_Name__c from Object_Analysis__c where id=:objAnalysisID];
        system.debug('objForAnalysis :: '+ objForAnalysis);
        objectName = objForAnalysis.Object_Name__c;

        fieldAnalysisList = new List<Field_Analysis__c>();
        fieldAnalysisListToDel = new List<Field_Analysis__c>();
        fieldAnalysisMap = new Map<string,Field_Analysis__c>(); 
        fieldAnalysisOldMap = new Map<string,Field_Analysis__c>(); 

        //string qStr = 'select Name,CreatedDate,LastmodifiedDate,createdBy.Name, LastmodifiedBy.Name from ' + objectName  ;
        //List<sObject> sobjList = Database.query(qStr);

        //System.debug('------------------1.0'+ sobjList);
        //Account obj = [select id, lastmodifieddate from Account];
        //objectName flds = [select CreatedDate,LastmodifiedDate,createdBy.Name, LastmodifiedBy.Name   from objectName];
        //System.debug('------------1.1'+ flds);
    }

    global Database.querylocator start(Database.BatchableContext BC) {
        system.debug('>>>>> Batch Start ');
        system.debug('-------------<' + Schema.getGlobalDescribe());
        GlobalDescribeMap = Schema.getGlobalDescribe();
        string fieldStr = '';

        system.debug('GlobalDescribeMap:: '+ GlobalDescribeMap.get('Object_Analysis__c'));
        //system.debug('GlobalDescribeMap desc:: '+ GlobalDescribeMap.get('Object_Analysis__c').getDescribe());        

        //System.Debug('----------->' + GlobalDescribeMap.get(objectName).getDescribe());
            Schema.DescribeSObjectResult objResult = GlobalDescribeMap.get(objectName).getDescribe();

        Map<String, Schema.SObjectField> objectFields = objResult.fields.getMap();

        fieldSet = new Set<string>(objectFields.keyset());

        fieldAnalysisList = [select id,name,Populated_On__c,Type__c 
                             from Field_Analysis__c where Object_Analysis__c=:objForAnalysisID ];


        System.debug('-------------------01'+fieldAnalysisList);
        for(Field_Analysis__c fldA : fieldAnalysisList){
            if(fieldSet.contains(fldA.name)){
                fieldAnalysisOldMap.put(fldA.name,fldA);
            }else{
                fieldAnalysisListToDel.add(fldA);
            }
        }


        for(Schema.SObjectField fieldToken : objectFields.values()){
            System.debug('--------------02'+fieldToken);
            Schema.DescribeFieldResult dr = fieldToken.getDescribe();
            System.debug('----------1'+dr);
            fieldStr += dr.getName() + ',';
            if(!fieldAnalysisOldMap.containskey(dr.getName())){
                Field_Analysis__c fa = new Field_Analysis__c();
                fa.name = dr.getName();
                fa.Label__c = dr.getLabel();
                fa.Type__c = string.valueof(dr.getType());
                fa.Populated_On__c = 0;
                fa.Object_Analysis__c = objForAnalysis.id;

                //fa.CreatedDate__c  = String.valueOf(dr.getName());
                //fieldAnalysisList.add(fa);

                fieldAnalysisOldMap.put(dr.getName(),fa);
            }else{
                fieldAnalysisOldMap.get(dr.getName()).Populated_On__c = 0; 
                fieldAnalysisOldMap.get(dr.getName()).Label__c = dr.getLabel();
               // fieldAnalysisOldMap.get(dr.getName()).CreatedDate__c = 'TEST';
                fieldAnalysisOldMap.get(dr.getName()).Type__c = string.valueof(dr.getType());
            }
        }
        fieldStr = fieldStr.substring(0, fieldStr.length()-1);
        string queryStr = 'select ' + fieldStr + ' from ' + objectName;
        system.debug('>> fieldSet ' + fieldSet);
        return Database.getQueryLocator(queryStr);
    }

    global void execute(Database.BatchableContext BC, List<sObject> scope){
      system.debug('>>>>> Batch execute ');
      recordCount += scope.size();
      system.debug('>> fieldAnalysisOldMap ' + fieldAnalysisOldMap);
      system.debug('>> fieldSet ' + fieldSet);
      for(sObject objRec: scope){
        for(string fieldName : fieldAnalysisOldMap.keyset()){
            if(fieldAnalysisOldMap.get(fieldName).Type__c == 'BOOLEAN'){
                if(objRec.get(fieldName)!= false)
                fieldAnalysisOldMap.get(fieldName).Populated_On__c += 1;  
            }else if(objRec.get(fieldName)!=null){
                fieldAnalysisOldMap.get(fieldName).Populated_On__c += 1; 
            }
        }
      }
    }   

    global void finish(Database.BatchableContext BC) {
        system.debug('>>>>> Batch finish ');
        objForAnalysis.Record_Count__c = recordCount;
        objForAnalysis.Last_Analyzed_Date__c = system.now();
        update objForAnalysis; // update total record count on Object analysis
        upsert fieldAnalysisOldMap.values(); // insert new field details and update existing field details
        if(fieldAnalysisListToDel.size()>0)
        delete fieldAnalysisListToDel; // remove deleted field details      

        //send email notification to the usr who started the Analysis
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        string objAnyURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + objForAnalysis.id;
        mail.setUseSignature(false);
        mail.setSaveAsActivity(false);
        User u = [select email from user where id=:userinfo.getUserId()];
        mail.setToAddresses(new List<string>{u.email});
        mail.setSubject('Object Analysis Status ');
        string mailBody = '<h2> Object Analysis for ' + objForAnalysis.name + ' is completed for the object ' + objForAnalysis.Object_Name__c + ' </h2><br/>';
        mailBody += '<a href="' + objAnyURL + '">' + objAnyURL  + ' </a><br/><br/>';
        mailBody += 'Regards, <br/> Object Analysis';
        mail.setHtmlBody(mailBody);
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });       
    }

}

Please Help

1 Answer 1

4

Describe call with Schema.getGlobalDescribe() is trying to look for an object; its API name is hardcoded without namespace, hence might not exists in org where package is installed.

To solve the issue, you would need to get the add a namespace prefix to the object name.

Refer this question to Dynamically get a namespace prefix.

Note: Never hardcode the object name in package and be careful with places where a namespace is required.


Relevant information from documentation-

Starting with Apex saved using Salesforce API version 28.0, the keys in the map that getGlobalDescribe returns are always prefixed with the namespace, if any, of the code in which it is running.

For example, if the code block that makes the getGlobalDescribe call is in namespace NS1, and a custom object named MyObject__c is in the same namespace, the key returned is NS1__MyObject__c.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .