2

I created a callable class for a managed packaged but I am unable to actually get an instance while calling it from outside the package.

In execute anonymous:

Type.forName returns null

Callable extension = (Callable) Type.forName('MyNamespace', 'CallableClass').newInstance();

Callable class stub:

public with sharing class CallableClass implements Callable {
    public Object call(String action, Map<String, Object> args) { }
}

I think I misunderstood how the Callable Interface behaves. I was under the impression this class could be marked as public and be accessible outside of the managed packaged

Does it need to be global?

3

No, the class doesn't need to be global, but to access it, you must have a way to access it globally. In other words, your package has to have a way to expose the class via a method somehow.

// Note: Probably don't do this in production code... //
global class KlassFactory {
  global static Object getTypeFromPackage(String klass) {
    return Type.forName('myns',klass).newInstance();
  }
}

...

public class MyHiddenImpl implements Callable {
  public Object call(String action, Map<String, Object> args) {
    return 'Hello World'; // Just an example
  }
}

Now, in your execute anonymous:

Callable ex = (Callable)myns.KlassFactory.getTypeFromPackage('MyHiddenImpl');
String result = (String)ex.call('dummyValue', null);
System.assertEquals('Hello World', result);

As long as the class implements a global interface, you can access methods from that global interface, without the implementation being exposed.

A more standard way to do this would be to expose methods that return various types:

global class KlassFactory {
  global static Callable getMyHiddenImpl() {
    return new MyHiddenImpl();
  }
}

This allows package developers to expose only methods they want to have called. Callable is a handy interface we can use, but you can also expose your own global interfaces. Note that once exposed, you cannot later hide them in later versions. Callable helps alleviate this problem by allowing the implementation to change without changing the exposed API.

2
  • If I want the class that implements the Callable interface to be global, does the call method need to be global as well? – TemporaryFix Apr 29 '20 at 18:10
  • 1
    @TemporaryFix No, interface methods can be either global or public and still be accessible outside the package, as the interface itself is global. – sfdcfox Apr 29 '20 at 18:13

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.