0

I'm currently working on refactoring a managed package that involves adding a new global method to a global class.

From what I've read on managed packages, you can't edit global classes, because Salesforce doesn't let you do that. So you'd have to use the @deprecated keyword. I've read the docs but it doesn't explain exactly how and where I add it. I tried adding the annotation to the class header but was greeted with the error:

Only managed identifiers can be marked deprecated

Do I have to explicitly create a new class just to add my one method?

  • Can you share the error message? – Raul Feb 13 '17 at 11:33
  • Sure, edited my post. – coldspeed Feb 13 '17 at 11:35
  • Unmanaged packages cannot contain code that uses the deprecated keyword. – RCS Feb 13 '17 at 11:39
  • There is no restriction on modification of global classes in managed packages but if you wish to write a newer or optimized version of existing global method you can use deprecated keyword in similar syntax as given by RCS. – Mukesh Verma Feb 13 '17 at 11:42
  • So I can add a new function to an existing global class without any issues? Alright, and if I wanted to modify the contents of a function in an abstract class, the procedure would be fundamentally different, right? – coldspeed Feb 13 '17 at 11:46
1

@shiva - It's not clear why you are not just bringing out a new version of the existing managed package. If do need to bring out a new managed package as a successor to an existing package, most likely you'd want to remove any classes with a deprecated annotation.

The @deprecated annotation means "Ideally, we'd just remove this component in the next major version, but existing subscribers may already be using it. Since we don't want to break existing installs, we'll at least keep new installs from using it, and leave it just as it is for existing subscribers."

Most often, we deprecate one component in favor of the other, and we want to steer people to the preferred version. Wikipedia has a good discussion of the whole notion of deprecation -- https://en.wikipedia.org/wiki/Deprecation

  • I'm down voting this answer because it suggests use of @deprecated which is a really bad idea. See my alternative answer for the reasons. – Phil W Sep 30 '18 at 10:19
1

Deprecation in Salesforce managed packages is very dangerous and doesn't work in the way you might expect. Deprecating a global (class/interface/method/enum etc.) does two things:

  1. As mentioned in an earlier answer, it prevents use of the component in new orgs whilst allowing it to continue to be used in existing orgs when upgraded to or through the package version that deprecated the component
  2. It locks that component so you can no longer maintain it.

It should also be noted that you cannot delete a global and that still applies in this case; you cannot delete deprecated global components. Even in major version releases from what I can see.

Normally (outside the Salesforce realm) when you deprecate something it can still be used and provides the original behaviour for a period of time before it is deleted by the developers (usually on the first major version release following the minor release that deprecated the component). However, because Salesforce's deprecation mechanism locks the component, preventing it from being modified, and does not allow deletion of the component, you cannot afford to take this approach.

If you really want to deprecate your global component, the first thing you must do is empty its implementation. Clearly this prevents the component from retaining the existing behaviour and therefore immediately "breaks" any subscriber org implementation that uses it still. If you don't empty the implementation, since you cannot modify the deprecated component, once published in a new package version, you can never remove or change signatures of any other components (e.g. other classes/methods) in your package that the deprecated component uses.

Another side-effect of this locking of the deprecated component's implementation is that you cannot maintain the component from release to release or even in a patch; a bug found in a deprecated component simply cannot be corrected if it exists in that component's implementation (rather than in other components used by the deprecated component).

Deprecation is a managed package hell. Don't do it. Salesforce urgently needs to fix deprecation so it works in a way compatible with any other software development environment and release process. I raised an idea, https://success.salesforce.com/ideaView?id=0873A000000lIJXQA2, to help address this but being an ISV-related issue I don't ever expect it to get implemented since it is too niche and won't get the required votes to be considered.

0

Use the deprecated annotation(@deprecated) to identify methods, classes, exceptions, enums, interfaces, or variables that can no longer be referenced in subsequent releases of the managed package in which they reside. This is useful when you are refactoring code in managed packages as the requirements evolve. New subscribers cannot see the deprecated elements, while the elements continue to function for existing subscribers and API integrations.

You can only deprecate code in case of managed package org.

@deprecated
// This method is deprecated. Use function2(String parm1) instead.
global void function1() {

}

Note: Unmanaged packages cannot contain code that uses the deprecated keyword.

  • I've seen this in the docs. But if I can't deprecate it in apex code then how do I do it after I create the package? And what if I want to replace the old deprecated class with one that has the same name but different functionality? – coldspeed Feb 13 '17 at 11:44
  • You need to deprecate in apex code only, while deploying it to production it will work. But in case of Unmanaged Package or developer org you will need to comment that piece of deprecated code before deploying. – RCS Feb 13 '17 at 11:48
  • AFAIK, @deprecate keyword can only be used in a managed package? – Raul Feb 13 '17 at 11:50
  • @RahulSharma can you see the above comment, i have mentioned that it will work in managed production environment. – RCS Feb 13 '17 at 11:53
  • I've recently gained access to the code that is supposed to reside in a managed package. My aim is to make modifications and then create a new managed package as an update to the existing one. One of the classes I'm supposed to change is a global abstract class. I'm sorry for the repetitive question, but I'm still not able to figure out how @deprecated fits in this context, or exactly where/when/how I use the annotation. – coldspeed Feb 13 '17 at 11:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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