Skip to main content

Salesforce Apex: Replacing and/or Removing Apex Classes

Working with code within the constraints of Salesforce's workflow can be a challenge.  First, you have the restriction on changing anything in production.  Second, you have the requirement for 75% or greater unit test coverage.  Third, you have the fact that certain metadata cannot be pushed to production through a changeset (which means the only way to sync record IDs is by re-deploying the development environment from production).

Fourth - and this is what I'd like to blog about today - you cannot delete classes from production through the Salesforce UI.  The only way to delete a class from production is to download the class (and its associated metadata file) into the Eclipse IDE (which you have previously set up with the Apex add-on), change the "status" flag to "Deleted", then deploy the changed metadata file to production.  And (here's the kicker)...sometimes it doesn't work because...reasons.

So let's start with the workflow of a file deletion.  We'll make the assumption that the class in question is simply no longer needed.  Here is the process:

  1. On the sandbox server, comment out the body of the file and any associated test classes
  2. Create an "outbound changeset" that includes the altered class files
  3. Upload the changeset to production Salesforce
  4. Wait five to ten minutes for the changeset to become available in production
  5. On the production server, check for "inbound changesets" - the one you pushed will probably be available by now (keep trying if it isn't)
  6. Click the "Validate" button and the "Run default tests" option and validate
  7. If there are any errors in any related classes, methods, triggers, etc...you will have to go back to the sandbox and fix them before you can deploy your changes again
  8. Once validation has passed, you can deploy your now commented-out file
  9. In Eclipse, right click on "Apex" at the top of your navigation panel
  10. Hover over the "Force.com" menu item, then select "Refresh from server"
  11. After refreshing, make sure you see the commented-out file. (If you don't see the file at all, you will need to toggle the view in your Force.com -> Project Properties -> Force.com -> Project Contents by clicking "Add/Remove...")
  12. Now find the metadata file for your class and its related test class. They will have the same class name but end with "-meta.xml"
  13. Toggle the "status" on each file to "Deleted" and save
  14. Right-click on the metadata file and from the Force.com menu, select "Save to server"
  15. You will have to select the environment to save to ("production") and then provide your Salesforce credentials for each save
  16. On production, open up the developer console (which allows you to look at your Apex classes, but not change them) and verify that the files are, in fact, deleted
  17. If the files are not deleted, close Eclipse and reopen, then start again from step #9 (above)
That's it!  That's all you have to do to delete an Apex class (basically, a Java class) from a Salesforce production instance.  Easy, right?

Okay, not so much.  But the really irksome thing is that just renaming a class requires all of the above steps.  In other words, if you rename a class in sandbox, you no longer have that class in sandbox but it still exists in production.  So that means that in production, you now have two classes with the same content duplicating the same work, possibly in a very destructive manner.

So to rename a class, you have to create another class with the name you want with the same content as your old class, then do steps 1 through 17 above but include your new classes in your changeset in step #3.  You MUST make sure that your old classes are commented out and your new classes are working in production or it could be catastrophic to your org and you will probably be fired.

Welcome to Salesforce development!

Comments

Popular posts from this blog

jQuery noUIslider Pip Label Customization

Recently, I was tasked with creating a slider element for a user to select their credit rating, of which the user can select from among: 'Poor', 'Fair', 'Good', 'Excellent' and 'Not Sure'.  Several problems presented themselves here: A drop-down box would be better, but that's not what the requirements specified. I already have several numeric sliders on my page and I want them all to match. I selected the jQuery noUi Slider library to create the numeric sliders. noUi Slider does not support string values - only numeric values. The "pips" (slider scale/labels) also does not support string values. Since the solution involved shifting my mindset, I wanted to document it here for future reference and maybe to help someone facing the same requirements. Here's my solution: Since there is really no numeric correlation to credit score (especially considering one of the options is "Not Sure"), I will just u

How to Create a new Case Record Type in Salesforce

Here are the specific steps for adding a case record type. Some steps may vary by organization but the process should be pretty similar to what is shown here. 1) Create a new page layout 2) Add any new case statuses to picklist 3) Edit case statuses that should indicate case is "closed" 4) Add any new case types to picklist 5) Add any new case reasons to picklist 6) Add any new case origins to picklist 7) Add any new fields to case object 8) Under Record Types, ensure the picklists have the correct values (i.e. - Reason/Type/Origin) 9) Within the Type field, edit "Reason" field dependencies matrix and add new reason(s) to types 10) Create a new support process (if not reusing an existing one) 11) Create the new record type (enable for all profiles) 12) Finalize the page layout (if needed) and check "Default" in Case Assignment checkbox under Layout Properties 13) Create approval queues (if needed) 14) Set up approv

View Helpers - Custom Output Parser

I was reviewing some blade view code recently and decided it was too verbose. There were some long output statements that were duplicated throughout the view and that always signals a need to refactor or come up with a better method. So I wanted to share (or at least document) what I came up with here. First, the issue: fields stored as boolean "0/1" in the database must be output in "Yes/No" format. Plus, if the field is blank (or null), that must be reflected as well. Add to that the uncertainty of whether the production Microsoft Azure database will return a string or integer value for 1 or 0. This problem necessitates a blade statement like: {{ $object->property === null || $object->property === "" ? "" : $object->property == 1 ? 'Yes' : 'No' }} Like I said...verbose! One solution might be to create a Laravel accessor for the boolean field in the model. But that would mean that if I want the actual boolean