Close Sun Nov 18 14:44:03 GMT 2018

Sneaky dynamic method invocation Part 2

Building a managed package but want to avoid dependencies? Apex has a few tricks up its sleeve to communicate across namespaces. Here's the latest one:

Example callee code:

global class Extension implements StubProvider {
  
  /**
   * Example method
   */
  private Blob provideLicense() {
    return Crypto.generateAesKey(128);
  }
  
  /**
   * Example dispatcher
   */
  global Object handleMethodCall(Object stub, String method, Type returnType, List<Type> argTypes, List<String> argNames, List<Object> argValues) {
    if (method == 'provideLicense') return provideLicense();
    throw new StringException('method not implemented yet');
  }
  
}

Here's what the calling code looks like:

Type reflector = Type.forName('pkg_ns.Extension');
StubProvider impl = (StubProvider)reflector.newInstance();
String license = impl.handleMethodCall(impl, 'provideLicense', String.class, null, null, null);

It works by using the StubProvider system interface as a shared entry point. The class to be executed is instrumented with handleMethodCall, which delegates to each method (or multiple methods!) you make available. This approach avoids:

  • extension packages,
  • compile-time binding to invoked code
  • serializing the arguments or return value (per toString)

Another way to stay out of dependency hell.



Related