2

I am working on a batch class and I was having some code to push into scratch org to test. But it is giving me duplicate variable error while pushing the code. After this, I tried to copy the code and directly pasted into scratch org and saved it without any error. Below is the code for the Batch Class, I had highlighted the line which is having the variable declared with the same name. But the second one is in a different scope. The code is working perfectly in scratch org but I am not able to push it using the SALESFORCE CLI

global with sharing class ThisIsBatchClass implements Database.Batchable<SObject>{
    global Database.querylocator start(Database.BatchableContext BC){
        return Database.getQueryLocator('SELECT Id FROM Account LIMIT 10);
    }

    global void execute(Database.BatchableContext BC, List<sObject> scope){
        Map<Id,sObject> newVersionMap = new Map<Id,sObject>();

    sObject[] newDistis = new sObject[]{};//Here I have declared the variable

    for(Account p : (Account[]) scope ){
        Pagereference pdf = Page.PDFController;
        pdf.getParameters().put('Id',p.Id);
        pdf.setRedirect(true);

        if(!Test.isRunningTest()){
            Blob pdfData = pdf.getContentasPdf();
            sObject newVersion = createObject('ContentVersion');
            newVersion.put('Title', 'Account_Summary_'+String.valueOf(System.Today()));
            newVersion.put('Description','Invoice for '+p.Name);
            newVersion.put('PathOnClient', 'Account_Summary_'+String.valueOf(System.Today())+'.pdf');
            newVersion.put('VersionData', pdfData);
            newVersion.put('Origin', 'H');
            newVersionMap.put(p.Id, newVersion);
        }
    }
    insert newVersionMap.values();
    if(!newVersionMap.isEmpty()){

        sObject[] newDistis = new sObject[]{};//Now this variable is declare again, which is in scope of If statement

        for(Id k: newVersionMap.keyset()){
            sObject c = newVersionMap.get(k);
            sObject newDisti = createObject('ContentDistribution');
            newDisti.put('ContentVersionId',(Id)c.get('Id'));
            newDisti.put('Name',(String)c.get('Title'));
            newDisti.put('RelatedRecordId',k);
            newDisti.put('PreferencesAllowPDFDownload',true);
            newDisti.put('PreferencesAllowOriginalDownload',false);
            newDisti.put('PreferencesAllowOriginalDownload',false);
            newDisti.put('PreferencesLinkLatestVersion',true);
            newDisti.put('PreferencesAllowViewInBrowser',true);
            newDistis.add(newDisti);

        }
        insert newDistis;
    }
}
global void finish(Database.BatchableContext BC){

}

public static sObject createObject(String typeName) {
    Schema.SObjectType targetType = Schema.getGlobalDescribe().get(typeName);
    if (targetType == null) {
        return null;
    }
    return targetType.newSObject(); 
}

}

migrated from salesforce.meta.stackexchange.com Jan 10 at 14:13

This question came from our discussion, support, and feature requests site for Salesforce administrators, implementation experts, developers and anybody in-between.

1

You've copied-pasted something incorrect or such. You are not allowed to have a variable shadow another variable this way. Here's a non-compiling script that demonstrates this:

public class q246196 {
    public void test() {
        String s;
        if(s == null) {
            String s = 'hello';
        }
    }
}

Duplicate variable: s


Conversely, the following is allowed:

public class q246196 {
    public void test() {
        {
            String s;
        }
        if(s == null) {
            String s = 'hello';
        }
    }
}

Here, the first s scope is terminated before the second begins. This is allowed. You are allowed a symbol (variable name) once at the class level, once at the function level, and once at the static level.

While an if statement does create a new scope, it shares its scope with the parent function in which it resides. The compiler is correct. If you were able to save this code in any org, it is a bug and should be reported to Salesforce.

  • 1
    Confusingly, Anonymous Apex appears to allow the shadowing unless a top-level scope is explicitly created. String a = 'Test'; if (true) { String a = 'Test'; } is legal. { String a = 'Test'; if (true) { String a = 'Test'; } } is not and yields the expected error. – David Reed Jan 10 at 15:32
  • @DavidReed Exec anon follows different rules. You shouldn't trust exec anon to follow the rules of Apex as strictly. Try using that class from my answer in exec anon verbatim, you'll get an error, as expected. – sfdcfox Jan 10 at 15:38
  • Oh, not disagreeing at all! Just noting one extra wrinkle where differing behavior can be observed. – David Reed Jan 10 at 15:40

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.