• haridsv
  • NEWBIE
  • 0 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 0
    Questions
  • 2
    Replies

I uploaded a class implementing the Database.batchable interface into our live environment. It ran with a couple of errors and I decided to remove it and go another route.

 

The problem is that I now seem to be unable to remove the class. I tried cleaning out the contents of the class, like thus:

 

 

global class CalcSummaryBatch {	
}

 

 

The class above saved successfully without any errors, but Salesforce still refuses to allow me to delete the class, or save it as Inactive.

 

Here's the error that I'm getting: "This apex class is referenced elsewhere in salesforce.com. Remove the usage and try again.: Apex Job - xxxxxxxxxxxxxxxxxxx."

 

Here's the log under Setup > Monitoring > Apex Jobs. I double-checked, and all jobs are at a Completed status:

(There are about 20 such messages as the one below, all with status "Completed", and all the Apex Job Ids are listed as why the class cannot be deleted, in the error above)

Action
 Submitted Date
Job Type
Status
Status Detail
Total Batches
Batches Processed
Failures
Submitted By
Completion Date
Apex Class
Apex Method
 <nothing listed here>
 4/10/2011 11:00 PM Batch Apex
Completed
 First error: Attempt to de-reference a null object 0 0 1 xxx 4/10/2011 11:00 PM CalcSummaryBatch  <nothing listed here>
...

I see what looks like a language bug in Apex (either that, or 'protected' has a surprising meaning in Apex).

 

According to the language reference: protected is defined as:

"This means that the method or variable is visible to any subclasses in the defining Apex class". Note that it says any *subclasses* *in* the defining apex class.

 

Here's what I see:

 

 

public class TestClass { public abstract class Base { protected abstract String protected_method(); public void protected_method_caller() { System.debug('Returning ' + protected_method()); } protected void is_this_really_protected() { System.assert(true, 'Not true'); System.debug('this is a test'); } } public class Derived extends Base { protected override String protected_method() { System.debug('Calling protected method'); System.assert(true, 'Not True'); return 'Test'; } } public class UnRelated { public void unrelated_method() { Derived d = new Derived(); d.is_this_really_protected();// THIS LINE SHOULD FAIL AS UNRELATED IS NOT A SUBCLASS

} } public testmethod static void test_protected_method() { Derived d = new Derived(); d.protected_method_caller(); } public testmethod static void test_unrelated_method() { UnRelated u = new UnRelated(); u.unrelated_method(); } }

 

In the above test case,  an unrelated inner class is able to call a protected method(as long as it is defined in the same outer class). (Ie. It is *in* the same defining class but not a *subclass*)

 

Now consider this:

 

// In base.cls public abstract class Base { protected abstract String protected_method(); public void protected_method_caller() { System.debug('Returning ' + protected_method()); // QUITE LEGITIMATE. SHOULD WORK! } } // In derived.cls public class Derived extends Base { protected override String protected_method() { System.debug('Calling protected method'); System.assert(true, 'Not True'); return 'Test'; } public static testmethod void testderived() { Derived d = new Derived(); d.protected_method_caller(); } }

 

What, to me, seems a fairly normal use of protected. Running this test fails with:

System.TypeException: Method is not visible: [Derived].protected_method()  

 

In this case, Base cannot see the overriden Derived protected_method(). NOTE: If I change the modifier in Derived to public override protected_method() {...}, it works. (Ie. it is a *subclass* but not *in* the same defining class.

 

Is this how it's supposed to behave? Or is this a bug?

 

thanks,

Vijay

 

  • April 11, 2009
  • Like
  • 0