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?

2 Answers 2


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.

  • If I want the class that implements the Callable interface to be global, does the call method need to be global as well? Apr 29, 2020 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, 2020 at 18:13

I can confirm that using a global class instead of public works.

global class PluginCallable implements Callable {
    global Object call(String action, Map<String, Object> args) {

call it like

Callable pluginCall = (Callable) Type.forName('PluginCallable').newInstance();
Map<String, Object> result = (Map<String, Object>) pluginCall.call(...);

My use case was: Managed package (published on AppExchange) calls a plugin which is an unlocked package (to be audited if needed) to receive a list of flows in the org.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .