I recently stumbled upon this error while making an update to an Apex class in one of my managed packages:
I was quite baffled by this because my change was minor logic within an existing method. Looking at the class definition it still implemented the Queueable interface:
A quick internet search later and I came across this stackoverflow post Why can’t class relationships in Salesforce managed packages be changed? The answer makes sense, since our class is global then subscriber orgs might be leveraging the methods and inheritance type we had defined in previously released versions of the package. So if we were to make any changes to that definition and contract then that could break code in subscriber orgs. That is a big no-no.
But again, I was baffled because I hadn’t changed the interfaces my code was implementing or change my constructors. So what gives?
Winter ’18 Apex Compiler Changes
In Winter ’18 there are some notable compiler changes that you should be aware of. Salesforce has documented the major behavioral changes and their suggested fixes in this knowledge article.
One of those changes was the root of my issue:
BEHAVIOR 6:
“Account” type binds to “Schema.Account” when namespace is null or empty. The compiler is not correctly requiring the use of the Schema namespace when there is a user-defined type with the same name.
Although I’m not aware of a user-defined type in my packaging org that conflicts with Queueable, nevertheless the solution was to explicitly implement System.Queueable in my class definition:
Please consider retweeting this post to get the message out to more Salesforce Developers. Thank you!