Java reflection on a message using MethodHandle

Some code I was looking at recently had an overloaded method and each method just accepted a different type argument. With Generics there are probably ways to reduce this clutter, or not.

Anyway, I started thinking about the original concept of OO; it was all about ‘messages’. But what is the difference between a ‘message’ as per Alan Kay and Smalltalk and a method’, née “subroutine” in Java? I guess it’s intent, design, and the other features of OOP?

Jump to example source code

Following this line of thought I wound up looking at how to invoke a public method on a class and that method in turn delegates to private methods that match the data within the message. BTW, this is not a new concept, it is an often used ‘idiom’, like in servlets and other backend service handlers.

The public method is the destination of a ‘message’. So I searched the web and found mention of the usual Reflection, Proxies, instanceof, and finally MethodHandles. The package java.lang.invoke contains the new approach to reflection introduced in Java 7. MethodHandle is the new class that makes all this possible.

Not much on MethodHandle on the web (search instead for: java “method handle”), but the API docs are very good and this blog post, “A glimpse at MethodHandle and its usage”, is all you need to get started. Below in Listing 1, a simple example is shown. Class Server has a single method that takes a String message and a parser.

The message contains the data that is used to determine the actual method to invoke. Simple, but the point is that this could be a JSON/XML string or some other data container. The parser is just me experimenting with callbacks, here the callback gets the data in the message. Yeah, I know, if the client can get the data, why not just send it? It’s just a ‘hello world’ example.

Example
In listing 1 the Service class exposes one method, send.

public class Service {	
    public Object send(String message, Parser parser) throws Throwable {
	Object pData = parser.parse(message);		

	MethodType methodType = 
          MethodType.methodType(
            Object.class,pData.getClass());		

	MethodHandle mh = MethodHandles.lookup()
         .findVirtual(
            Service.class, "call", methodType);		

	Object actual = mh.invoke(this,pData);		
	return actual;
    }

    @SuppressWarnings("unused")
    private Object call(String data) {
	System.out.println("in string method ...");
	return "string data";
    }

    @SuppressWarnings("unused")
    private Object call(Integer data) {
	System.out.println("in int method ...");
	return new Integer(42);
    }
	
    public interface Parser{
	public Object parse(String s); 
    }
}

Listing 1

In listing 2, the Main class sends the message to the Service class.

public class Main {    
    public static void main(String[] args) throws Throwable {
      Service app = new Service();
      Service.Parser parser = new Parser();   

      Object actual = app.send("some text", parser);
      assert actual == "string data" 
        : "Should have returned 'some data' string";
        
      actual = app.send("number: 42",parser);
      Integer expected = 42;
      assert (actual.equals(expected)) 
         : "Should have returned Integer with value 42";
  }
    
  static class Parser implements Service.Parser{                  
      @Override
      public Object parse(String s) {
          if(s.startsWith("number:")){                            
              Integer i = Integer.valueOf(  
                  (s.split(":")[1]).trim() );
              return i;
          }
          
          return s;
      }
  }
}

Listing 2

Not earthshaking of course. The output is:
in string method …
in int method …

The example is somewhat like the javax.servlet.Servlet class, only one method, service(ServletRequest req,ServletResponse res) is also used, and usually one invokes other methods based on the “message” params.

I can see the use of MethodHandles leading to some powerful mojo.

Links

Java Reflection Method Invoke Using Fluent Interface

Here is an example of creating a fluent builder interface for invoking a method via Java Reflection. While the code to invoke Java methods via reflection is not complex, it can be improved. We can introduce a ‘façade’ and this façade can use the fluent builder pattern. Of course, doing all this just to invoke a method is not the point, but to illustrate or experiment with the pattern.

One example of using this is:

.name(“greet”).on(anObject).with(“Hello world!”).of(String.class).invoke();

Or in prose, this is what the above is doing: Invoke method name “greet”, on object anObject, with the argument “Hello world!”, of class types String.class. Note that some of the words in the prose were used as the method names. Fluent Interface is somewhat of a mini Domain Specific Language (mDSL).

The final invoke() will use the information and generate whatever is required in order to perform the method invocation. More on this later.

Background
Fluent Interfaces (not just about chained setters) are an old concept that is becoming more well known and used. One popular blog post was FluentInterface by Martin Fowler. Since then there are many resources on this.

The main motivation was the issues with current practices in creating interfaces. In Item 2: Consider a builder when faced with many constructor parameters by Joshua Bloch, the disadvantages in “Telescoping constructors” and the JavaBean pattern are analyzed and why a builder may be more useful.

I wanted to learn more about this, so I wanted an approachable application, but not too easy. Reflective invocation of a method is very doable. Currently, you must find a Method, then invoke with the correct arguments. But, all this is kind of kludgy, for example the Method‘s invoke method is

public Object invoke(Object obj, Object… args) throws …

But, if the underlying method is static, then the obj argument is ignored. It may be null. So, there could have been an overload for this situation that only required the arguments. Just reduces the API noise. And that null use is suspect. In my opinion any API that deliberately allows the use of null is nuts. Oops, other language are all about null, like JavaScript.

 

Approach
We create a fluent interface that combines the Method look up and the invocation on an object into a Facade. Then the invoke method of the builder will perform the actual invocation and it will use whatever is available to properly perform this.

In more complex situations, a builder can employ various techniques to create the final object or invoke the desired action. One technique is to execute a Decision Table.

One complication is that I wanted this to be usable as a static utility class. Thus, a static method of the utility class will create a nested class that implements the builder pattern.

Example implementation
Source code available at gist: https://gist.github.com/josefbetancourt/3ffcb3044e558fc1b3e8

The list of “verbs” is:

  1. name: what is the method name?
  2. on: on what object or class to invoke?
  3. of …: types of arguments?
  4. using …: using what parameters?
  5. nosy: is method private?
  6. method: use a known method object?
  7. clazz: instead of method what class?
  8. returning: what type of object to return?
  9. invoke: Invoke by figuring out what to do.

Of course, not all of these are required to invoke a method, not even a target object, since a static method can be invoked on a class.

An example use is:

ReflectionUtil.invokes()
   .name(“hello”).on(innerTest).using(“Hello world!”).of(String.class).invoke();
 

Code example

[expand title=”Listing 1, implementation”]

package com.octodecillion.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;

/**
 * Reflection Invoker using Fluent Builder.
 * 
 * Example is a singleton utility class that contains
 * a facade to a fluent builder pattern.
 * 
 * @author jbetancourt
 * @since 20130201T2233-5
 */
public final class Example {

	private static final Example instance = new Example();

	private Example() {
		// it's a singleton utility class.
	}

	public static Invoker invokes() {
		return instance.new Invoker();
	}

	/**
	 * Example use:  
	 * invokes().name("hello").on(innerTest).using("Hello world!").of(String.class).invoke();
	 * 
	 */
	class Invoker {
		private String name;
		private Object object;
		private Class<? extends Object> clazz;
		private Class<?>[] classes;
		private Object[] params;
		private Method method;
		private boolean allowPrivate;

		public Invoker name(final String name) {
			this.name = name;
			return this;
		}

		public Invoker on(final Object obj) {
			object = obj;
			return this;
		}

		public Invoker on(final Class<?> clz) {
			clazz = clz;
			return this;
		}

		public Invoker of(final Class<?>... classes) {
			this.classes = classes;
			return this;
		}

		public Invoker using(final Object... params) {
			this.params = params;
			return this;
		}

		public Invoker nosy() {
			allowPrivate = true;
			return this;
		}

		public Invoker method(final Method method) {
			this.method = method;
			return this;
		}

		public <T> Invoker returning(@SuppressWarnings("unused") final T clazz) {
			return this;
		}

		public Object invoke() throws NoSuchMethodException, SecurityException,
				IllegalAccessException, IllegalArgumentException,
				InvocationTargetException {

			boolean paramsButNoTypes = (method == null)
					&& ((params != null) && (classes == null));

			if (paramsButNoTypes) {
				throw new IllegalStateException(String.format(
						"params:%s,classes:%s", params, classes));
			}

			if (method == null) {
				if (object == null) {
					method = clazz.getDeclaredMethod(name, classes);
				} else {
					Class<? extends Object> clz = (clazz == null ? object
							.getClass() : clazz);
					method = clz.getDeclaredMethod(name, classes);
				}
			}

			if (allowPrivate) {
				return invokePrivate();
			}

			return method.invoke(object, params);

		}

		private Object invokePrivate() {
			try {
				final Object objF = object;
				final Method methodF = method;
				final Object[] paramsF = params;

				return AccessController
						.doPrivileged(new PrivilegedExceptionAction<Object>() {
							Object result;

							@Override
							public Object run() throws Exception {
								if (!methodF.isAccessible()) {
									methodF.setAccessible(true);
								}

								result = methodF.invoke(objF, paramsF);
								return result;
							}

						});
			} catch (Exception ex) {
				throw new IllegalStateException("Cannot set method,'" + method
						+ "' accessible.", ex);
			}
		}
	} // end class Invoker

} // end class Example

[/expand]

Note that the above code is not necessarily usable in the real world. It has not been reviewed for thread safety, safe publishing of create object, and other possible issues.

 

Example Test

[expand title=”Listing 2, unit test”]

package com.octodecillion.utils;

import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * 
 * 
 * @author jbetancourt
 *
 */
@RunWith(JUnit4.class)
public class ExampleTest {

	/** test on class with static public methods */
	@Test
	public final void invokes_on_static() throws Exception {

		Object actual = Example.invokes().name("hello")
				.on(WithStaticMethod.class).using("Hello world!")
				.of(String.class).invoke();

		assertThat((String) actual, is("Hello world!"));

	}

	/** test on class with static private methods */
	@Test
	public final void invokes_on_private_method() throws Exception {
		WithStaticMethod obj = new WithStaticMethod();
		Object actual = Example.invokes().name("privateHello").on(obj).nosy()
				.invoke();

		assertThat((String) actual, is("Hello private world!"));

	}

	static class WithStaticMethod {
		public static String hello(final String msg) {
			return msg;
		}

		private String privateHello() {
			return "Hello private world!";
		}

	}

	/** test on inner class with public methods */
	@Test
	public final void testInvokes() throws Exception {

		class InnerClass {
			public String hello(final String msg) {
				return msg;
			}

			public String hello() {
				return "Hello default world!";
			}

			private String privateHello() {
				return "Hello private world!";
			}

		} // end InnerTest

		InnerClass innerTest = new InnerClass();

		Object actual = Example.invokes().name("hello").on(innerTest)
				.using("Hello world!").of(String.class).invoke();

		assertThat((String) actual, is("Hello world!"));

		actual = Example.invokes().name("hello").on(innerTest).invoke();

		assertThat((String) actual, is("Hello default world!"));

		actual = Example.invokes().name("privateHello").on(innerTest).nosy()
				.invoke();

		assertThat((String) actual, is("Hello private world!"));

	}

}

[/expand]

 

Summary
Presented was an easy example of the start of a possible Fluent Interface for a utility. One problem though, is that the invoke method will attempt to invoke with what was supplied by the developer. In a more complex application of the Fluent Interface this can lead to run-time exceptions if this is not done correctly, or if the invoke or build method is not up to snuff. An interesting pattern Step Builder pattern by Marco Castigliego addresses some of the shortcomings of a pure Fluent Builder pattern. In the Step Pattern the steps, guided by interfaces, “guides” the creation of the object or action.

 

Links

Updates
March 4, 2013, 22:07: Now that I finished the above learning exercise, I wanted to find out how others did something similar. So far, found the FEST which has a Fluent Reflection module. So, I wasn’t off to a bad start, but FEST is more comprehensive! An interesting post by Alex Ruiz is: Fluent interfaces: don’t chain for the sake of chaining