title: Use LambdaMetafactory to invoke one-arg method on class instance obtained from other classloader
body: <p>Based on <a href="https://stackoverflow.com/questions/30695742/how-should-i-be-using-lambdametafactory-in-my-use-case">this stackoverflow answer</a>, I am attempting to instantiate a class using reflection and then invoke a one-argument method on it using <code>LambdaMetafactory::metafactory</code> (I tried using reflection, but it was rather slow).</p>
  
  <p>More concretely, I want to create an instance of <code>com.google.googlejavaformat.java.Formatter</code>, and invoke its <code>formatSource()</code> method with the following signature: <code>String formatSource(String input) throws FormatterException</code>.</p>
  
  <p>I have defined the following functional interface:</p>
  
  <pre><code>@FunctionalInterface
  public interface FormatInvoker {
    String invoke(String text) throws FormatterException;
  }
  </code></pre>
  
  <p>and am attempting to execute the following code:</p>
  
  <pre><code>try (URLClassLoader cl = new URLClassLoader(urls.toArray(new URL[urls.size()]))) {
    Thread.currentThread().setContextClassLoader(cl);
  
    Class&lt;?&gt; formatterClass =
        cl.loadClass("com.google.googlejavaformat.java.Formatter");
    Object formatInstance = formatterClass.getConstructor().newInstance();
  
    Method method = formatterClass.getMethod("formatSource", String.class);
    MethodHandles.Lookup lookup = MethodHandles.lookup();
    MethodHandle methodHandle = lookup.unreflect(method);
    MethodType type = methodHandle.type();
    MethodType factoryType =
        MethodType.methodType(FormatInvoker.class, type.parameterType(0));
    type = type.dropParameterTypes(0, 1);
  
    FormatInvoker formatInvoker = (FormatInvoker)
      LambdaMetafactory
          .metafactory(
              lookup,
              "invoke",
              factoryType,
              type,
              methodHandle,
              type)
          .getTarget()
          .invoke(formatInstance);
  
    String text = (String) formatInvoker.invoke(sourceText);
  } finally {
    Thread.currentThread().setContextClassLoader(originalClassloader);
  }
  </code></pre>
  
  <p>When I run this code, the call to <code>LambdaMetafactory::metafactory</code> fails with the following exception:</p>
  
  <pre><code>    Caused by: java.lang.invoke.LambdaConversionException: Exception finding constructor
          at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:229)
          at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:304)
          at com.mycompany.gradle.javaformat.tasks.JavaFormatter.formatSource(JavaFormatter.java:153)
          ... 51 more
      Caused by: java.lang.IllegalAccessException: no such method: com.delphix.gradle.javaformat.tasks.JavaFormatter$$Lambda$20/21898248.get$Lambda(Formatter)FormatInvoker/invokeStatic
          at java.lang.invoke.MemberName.makeAccessException(MemberName.java:867)
          at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1003)
          at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1386)
          at java.lang.invoke.MethodHandles$Lookup.findStatic(MethodHandles.java:780)
          at java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite(InnerClassLambdaMetafactory.java:226)
          ... 53 more
      Caused by: java.lang.LinkageError: bad method type alias: (Formatter)FormatInvoker not visible from class com.delphix.gradle.javaformat.tasks.JavaFormatter$$Lambda$20/21898248
          at java.lang.invoke.MemberName.checkForTypeAlias(MemberName.java:793)
          at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:976)
          at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000)
          ... 56 more
  </code></pre>
  
  <p>I've read through a number of stackoverflow answers about <code>LambdaMetafactory</code> and read the <code>LambdaMetafactory</code> documentation, but have not been able to figure out what I am doing wrong. I am hoping that somebody else will be able to.</p>
  
  <p>Thank you in advance for your help.</p>