JDK-7034341 : MethodType.hasWrappers() throws IAE if a method type contains an argument of the java.lang.Void type
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 7
  • Priority: P2
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2011-04-06
  • Updated: 2012-03-22
  • Resolved: 2011-05-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7Resolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
Please see the minimized test below to reproduce the issue.

Minimized test:
===============
$ cat test.java
import java.lang.invoke.MethodType;
import static java.lang.invoke.MethodType.*;
import java.util.List;
import java.util.ArrayList;

public class test {

    private final static Class[] RETURN_TYPES = {
        void.class, int.class
    };

    private final static Class[] PARAM_TYPES = {
        int.class, Void.class, Integer.class
    };

    public static void main(String[] args) {
        for (int i = 0;  i < RETURN_TYPES.length; i++) {
            Class rtype = RETURN_TYPES[i];
            boolean hasWraps = isWrapperType(rtype);
            List params = new ArrayList();

            for (Class ptype : PARAM_TYPES) {
                params.add(ptype);
                hasWraps |= isWrapperType(ptype);
                MethodType mt = methodType(rtype, params);
                
                try {
                    if (isWrapperType(rtype) != mt.hasWrappers()) {
                        System.out.println("hasWrappers() failed for method type "
                                + mt + ": expected \"" + isWrapperType(rtype) + "\", "
                                + "was given \"" + mt.hasWrappers() + "\"");
                    }
                } catch (IllegalArgumentException iae) {
                    System.out.println("IllegalArgumentException was thrown "
                            + "in hasWrappers() for method type " + mt);
                }
            }
        }
    }

    private static boolean isWrapperType(final Class cl) {
        if (cl.equals(Void.class) || cl.equals(Boolean.class)
                || cl.equals(Byte.class) || cl.equals(Character.class)
                || cl.equals(Short.class) || cl.equals(Integer.class)
                || cl.equals(Long.class) || cl.equals(Float.class)
                || cl.equals(Double.class)) {
            return true;
        }
        return false;
    }
}

$ javac test.java
Note: test.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

$ java -showversion -verify -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic test
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b136)
Java HotSpot(TM) Server VM (build 21.0-b06, mixed mode)

IllegalArgumentException was thrown in hasWrappers() for method type (int,Void)void
IllegalArgumentException was thrown in hasWrappers() for method type (int,Void,Integer)void
IllegalArgumentException was thrown in hasWrappers() for method type (int,Void)int
IllegalArgumentException was thrown in hasWrappers() for method type (int,Void,Integer)int

Comments
EVALUATION After fixing the bug, the test case needs fixing: - hasWraps |= isWrapperType(ptype); + hasWraps |= isWrapperType(ptype) && ptype != Void.class; MethodType mt = methodType(rtype, params); - if (isWrapperType(rtype) != mt.hasWrappers()) { + if (hasWraps != mt.hasWrappers()) { Grouping with 7044892.
17-05-2011

EVALUATION Wrap/unwrap logic needs to be more careful with the type Void.
13-05-2011