Java 7 : More dynamics

Like you know (or perhaps not, nevermind), the Java bytecode doesn’t support dynamic method invocation. There are three supported invocations modes : invokestatic, invokespecial, invokeinterface or invokevirtual. These modes allows to call methods with known signature. We talk of strongly typed language. This allows to to make some checks directly at compile time.

On the other side, the dynamic languages use dynamic types. So we can call a method unknown at the compile time, but that’s completely impossible with the Java bytecode. The dynamic languages based on the Java Runtime must use Java Reflection to make dynamic invocations.

In Java 7, we’ll see a new feature, the JSR 292. This JSR add new method invocation mode : invokedynamic. With that new bytecode keyword, we can call method only known at runtime.

This JSR only impact the bytecode not the language. But with Java 7 we’ll see a new package java.dyn that use this new functionality. That package will improve the performances of Java reflection and mainly the performances of the others languages that run in the JVM.

MethodHandle

The MethodHandle class allows to manipulate a reference to a method. It’s like a pointer to a method. With that features, we avoid the heavy process of reflection.

With that class, we can have informations about the method (return type and parameters) and invoke that method with a special invoke() method that can be called with any number of parameters. To create a MethodHandle we use the MethodHandles factory.

Here is an example :

JComboBox combo = new JComboBox();

MethodHandle handle = MethodHandles.lookup().findVirtual(JComboBox.class, "setModel", MethodType.make(void.class, ComboBoxModel.class));

handle.invoke(combo, new CustomComboModel());

Of course, this example is completely useless but shows the process of invoking a method using Method. There are some differences with Reflection :

  • The call to invoke() is optimized by the JVM with calling directly the target method like any other call.
  • The performances are a lot better, almost the same as a standard call.
  • The cheks on the method are made when we create the MethodHandle Object not at all the invoke() calls.

InvokeDynamic

The second class of this new package is the InvokeDynamic class. This is even more weird than the first one, because this class has no methods. But we can invoke any methods on it.

InvokeDynamic.setModel(new CustomComboModel());
InvokeDynamic.init();
Date today = InvokeDynamic.getDate();
//... You can call any valid method

All that calls will be compiled with InvokeDynamic. Namely, all that calls will not be checked at compile time but at runtime.

To use that mechanism, we must define a bootstrap mechanism who will do the conversion between the method calls on InvokeDynamic and the really Method (through MethodHandle) to invoke. When we invoke the method, the JVM use that bootstrap method to get the MethodHandle and invoke it.The JVM use a cache for the MethodHandle to improve performances. So, only the first dynamic call will be searched in the bootstrap method.

To register the bootstrap method, we have to use the Linkage.registerBootstrapMethod(String methodName) method.

Here is a really basic example of a boot strap method. That method only use the name of the called method and return the MethodHandle to the same method in the Utility class with no args. Of course, that kind of bootstrap method must not be used, but that shows the basics of develop that kind of methods.

private static CallSite bootstrap(Class caller, String name, MethodType type) {
    CallSite site = new CallSite(caller, name, MethodType.make(void.class));
    site.setTarget(MethodHandles.lookup().findStatic(Utility.class, name, MethodType.make(void.class)));
    return site;
}

References of type InvokeDynamic can take any types of objects :

InvokeDynamic dynamicString = "Hello World";
InvokeDynamic dynamicCombo = new JComboBox();
InvokeDynamic dynamicNumber = 1;

With that, we can dynamically call a method on the target :

dynamicString.aSimpleMethod();

Here we are. I think we’ve covered the main features of this new package.

Of course these classes will mostly be used by dynamic languages developers instead of standard programmers but the MethodHandle class can be useful to improve reflection performances in simple programs. I think it’s a great new features but that will not be used by everybody.

 

  • joonas

    I’m not entirely new to JSR 292 but what makes MethodHandles superior to Method.invoke()…? The points you present could have just made “under the hood” or could they? Just the same you seem to fetch an instance of class, now it’s just MethodHandle, not Method.

    The invoke method seems (by your example) to have identical signature compared to Java5 version. Are MethodHandles somehow lighter in weight? Why couldn’t this functionality be expressed by upgrading reflect’s Method? Are there differences in for example, not finding the method in question or something like that?

    • Baptiste Wicht

      I think they doesn’t want to change the reflection who’s using by a lot of projects. This new API has less exceptions and is, i think, easier to use.

      Then the cheks are only made at the creation of the MethodHandle not when the invoke() method is called, unlike Reflection. Moreover, the new API has functionalities that the Reflection doesn’t provide. With MethodHandle, you can manipulate the signature of the method called by the MethodHandle, by example, you can set the value of a parameter. So :

      handle.invoke(combo, new CustomComboModel());

      become :

      handle = handle.insertArgument(handle, 0, combo);
      handle.invoke(new CustomComboModel());

      The API is really more powerful than the Reflection one.

      But there is perhaps another reason to not transform the Reflection by this mechanism.

  • joonas

    I’m not entirely new to JSR 292 but what makes MethodHandles superior to Method.invoke()…? The points you present could have just made “under the hood” or could they? Just the same you seem to fetch an instance of class, now it’s just MethodHandle, not Method.

    The invoke method seems (by your example) to have identical signature compared to Java5 version. Are MethodHandles somehow lighter in weight? Why couldn’t this functionality be expressed by upgrading reflect’s Method? Are there differences in for example, not finding the method in question or something like that?

    • Baptiste Wicht

      I think they doesn’t want to change the reflection who’s using by a lot of projects. This new API has less exceptions and is, i think, easier to use.

      Then the cheks are only made at the creation of the MethodHandle not when the invoke() method is called, unlike Reflection. Moreover, the new API has functionalities that the Reflection doesn’t provide. With MethodHandle, you can manipulate the signature of the method called by the MethodHandle, by example, you can set the value of a parameter. So :

      handle.invoke(combo, new CustomComboModel());

      become :

      handle = handle.insertArgument(handle, 0, combo);
      handle.invoke(new CustomComboModel());

      The API is really more powerful than the Reflection one.

      But there is perhaps another reason to not transform the Reflection by this mechanism.

  • http://www.howtoloseweightfastest.com/ Brine

    Are they also adding specializing generics? Type Erasure and Boxing are a real pain in the ass, and are the main reason I’ve stayed with .NET for so long…

  • http://www.howtoloseweightfastest.com/ Brine

    Are they also adding specializing generics? Type Erasure and Boxing are a real pain in the ass, and are the main reason I’ve stayed with .NET for so long…

  • wanderer

    Can you explain a bit more about the registration of the invoke dynamic bootstrap mechanism? Am I right to believe that there’s a single static bootstrap mechanism for the entire JVM? And not one for each InvokeDynamic instance — indeed it looks like all InvokeDynamic’s ‘dynamic’ methods are static? If so, why this static approach?

    • Baptiste Wicht

      There is one bootstrap method for each caller class. InvokeDynamic has no methods, it’s only a syntactic marker on which we can make every method calls we want.

  • wanderer

    Can you explain a bit more about the registration of the invoke dynamic bootstrap mechanism? Am I right to believe that there’s a single static bootstrap mechanism for the entire JVM? And not one for each InvokeDynamic instance — indeed it looks like all InvokeDynamic’s ‘dynamic’ methods are static? If so, why this static approach?

    • Baptiste Wicht

      There is one bootstrap method for each caller class. InvokeDynamic has no methods, it’s only a syntactic marker on which we can make every method calls we want.

  • Matt

    Don’t mean to be too pedantic, but what you refer to as strong typing is static typing. A type system can be strong and dynamic.

    • Baptiste Wicht

      Thanks, i didn’t know that :)

  • Matt

    Don’t mean to be too pedantic, but what you refer to as strong typing is static typing. A type system can be strong and dynamic.

    • Baptiste Wicht

      Thanks, i didn’t know that :)

  • http://www.modularhomesnetwork.com Manufactured Homes

    Can you explain how java programming method handle.

  • http://www.findprefab.com Manufactured Home

    Java software done the great job . Thanks for the article.

  • http://www.findprefab.com Manufactured Houses

    It’s more exiting. Thanks for the site.