2

We have a global apex interface in a managed package that enables a subscriber org to transform a field value during a calculation in our package.

 global interface CustomCallable {
    Object execute(String input);
}

We include the Interface in our logic like this:

public Object transform(String value, String className) {
    Type rawTransformator = Type.ForName(className);
    CustomCallable castedTransformator = (CustomCallable) rawTransformator.newInstance();
            
    return castedTransformator.execute(value);
}

Since the latest critical update we receive the error message:

{"errorMessage":"Interface Run Initialization has failed, Interface Type not correctly configured, Could not instantiate class: System.TypeException: MyCustomClassName does not have a no-arg constructor\n(System Code)\n\n\n\n\n\n\n\n\n\n"}

The critical update information states:

Also, regardless of API version, construction of abstract classes or interfaces is no longer allowed even when the type is visible and can be referenced using Type.forName.
  1. Is my interpretation correct that indeed the logic we used to include custom apex into our package should be prevented by this update?
  2. Do you have any suggestion for a workaround that can be used?
5

This change requires the "MyCustomClassName" class to:

  1. Be global (this was actually already the case) in order to allow the managed package's own code to create an instance of it.
  2. Now have a global, no-arg constructor that the managed package can call.

So it needs to look something like:

global class MyCustomClassName implements thepackage.CustomCallable {
    global MyCustomClassName() {
    }

    ...
}

By the way, the "Also..." statement in the critical update reveals a potential breaking change introduced in Apex regardless of API version. If you had something like:

public abstract MyClass {
    public static MyClass getInstance() {
        return (MyClass) MyClass.class.newInstance();
    }
}

Even though it shouldn't have, logically speaking, this would have worked before this critical update as long as there were no actual abstract methods in MyClass (virtual methods could exist). However, this no longer works because the ability to successfully call Type.newInstance() for a type that is abstract has been revoked. In this scenario MyClass must now be defined as public virtual class instead.

That Salesforce made this change is understandable, but the fact that it is retrospectively applied on earlier API versions is, IMHO, really unpleasant and can cause packages that were working to stop working.

2
  • Not quite but you brought me on track. The constructor was indeed public and on top of that it was an overloaded constructor and the second version had an argument. After removing the second version and making the no argument version global all worked well. Many Thanks – Robert Méndez Aug 24 '20 at 17:49
  • The alternative, arg constructor(s) should not be an issue and if they are I suggest this is a bug in apex. – Phil W Aug 24 '20 at 18:53

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.