title: Java access bean methods with LambdaMetafactory
body: <p>my question is strongly related to <a href="https://stackoverflow.com/questions/26775676/explicit-use-of-lambdametafactory">Explicit use of LambdaMetafactory</a> 
  in that thread, some very good examples are provided to use the LambdaMetafactory to access a static method of a class; however, I wonder what is the equivalent code to access a non static field of an existing bean instance. It seems really hard to find an example and every attempt I performed ended up in non working code. </p>
  
  <p>This is the bean code:</p>
  
  <pre><code>class SimpleBean {
      private Object obj= "myCustomObject";
      private static Object STATIC_OBJECT = "myCustomStaticObject";
      public Object getObj() {
          return obj;
      }
      public void setObj(final Object obj) {
          this.obj = obj;
      }
      public static Object getStaticObj() {
          return STATIC_OBJECT;
      }
      public static void setStaticObj(final Object obj) {
          STATIC_OBJECT = obj;
      }
  }
  </code></pre>
  
  <p>Here a working unit test that successfully access the static method "getStaticObj()":</p>
  
  <pre><code>    @Test
  public void accessStaticMethod() throws Throwable
  {
      MethodHandles.Lookup caller = MethodHandles.lookup();
      Method reflected = SimpleBean.class.getDeclaredMethod("getStaticObj");
      MethodHandle methodHandle = caller.unreflect(reflected);
      CallSite site = LambdaMetafactory.metafactory(caller,
              "get",
              MethodType.methodType(Supplier.class),
              MethodType.methodType(Object.class),
              methodHandle,
              MethodType.methodType(Object.class));
      MethodHandle factory = site.getTarget();
      Supplier r = (Supplier) factory.invoke();
      assertEquals( "myCustomStaticObject", r.get());
  }
  </code></pre>
  
  <p>Now here my failing attempts to access the non static "getObj()" method:</p>
  
  <pre><code>    @Test
  public void accessNonStaticMethodTestOne() throws Throwable
  {
      SimpleBean simpleBeanInstance = new SimpleBean();
  
      MethodHandles.Lookup caller = MethodHandles.lookup();
      MethodHandle methodHandle = caller.bind(simpleBeanInstance, "getObj", MethodType.methodType(Object.class));
      assertEquals("myCustomObject", methodHandle.invoke());
  
      // This test fails here with exception:
      // java.lang.IllegalArgumentException: not a direct method handle
      CallSite site = LambdaMetafactory.metafactory(caller,
              "get",
              MethodType.methodType(Supplier.class),
              MethodType.methodType(Object.class),
              methodHandle,
              MethodType.methodType(Object.class));
  
      MethodHandle factory = site.getTarget();
      Supplier r = (Supplier) factory.invoke();
      assertEquals( "myCustomObject", r.get());
  
  }
  
  @Test
  public void accessNonStaticMethodTwo() throws Throwable
  {
  
      SimpleBean simpleBeanInstance = new SimpleBean();
  
      MethodHandles.Lookup caller = MethodHandles.lookup();
  
      Method reflected = SimpleBean.class.getDeclaredMethod("getObj");
      MethodHandle methodHandle = caller.unreflect(reflected);
  
      // This test fails here with exception:
      // java.lang.invoke.LambdaConversionException: Incorrect number of parameters
      CallSite site = LambdaMetafactory.metafactory(caller,
              "get",
              MethodType.methodType(Supplier.class),
              MethodType.methodType(Object.class),
              methodHandle,
              MethodType.methodType(Object.class));
  
      MethodHandle factory = site.getTarget();
      factory = factory.bindTo(simpleBeanInstance);
      Supplier r = (Supplier) factory.invoke();
      assertEquals( "myCustomObject", r.get());
  
  }
  
  
  @Test
  public void accessNonStaticMethodThree() throws Throwable
  {
  
      SimpleBean simpleBeanInstance = new SimpleBean();
  
      MethodHandles.Lookup caller = MethodHandles.lookup();
  
      Method reflected = SimpleBean.class.getDeclaredMethod("getObj");
      MethodHandle methodHandle = caller.unreflect(reflected);
  
      CallSite site = LambdaMetafactory.metafactory(caller,
              "get",
              MethodType.methodType(Supplier.class),
              MethodType.methodType(Object.class, SimpleBean.class),
              methodHandle,
              MethodType.methodType(Object.class, SimpleBean.class));
  
      MethodHandle factory = site.getTarget();
  
      //This test fails here with exception:
      // java.lang.IllegalArgumentException: no leading reference parameter: spike.LambdaBeanAccessAtRuntimeTest$SimpleBean@4459eb14
      factory = factory.bindTo(simpleBeanInstance);
      Supplier r = (Supplier) factory.invoke();
      assertEquals( "myCustomObject", r.get());
  
  }
  </code></pre>
  
  <p>Every attempt has a different negative result, I really hope someone is abe to help me to have at least one test working fine.</p>