package cucumber.runtime.java8;

import cucumber.runtime.CucumberException;
import cucumber.runtime.java.TypeIntrospector;
import sun.reflect.ConstantPool;

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.List;

public class ConstantPoolTypeIntrospector implements TypeIntrospector {
    private static final Method Class_getConstantPool;

    static {
        try {
            Class_getConstantPool = Class.class.getDeclaredMethod("getConstantPool");
            Class_getConstantPool.setAccessible(true);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static final TypeIntrospector INSTANCE = new ConstantPoolTypeIntrospector();

    @Override
    public Type[] getGenericTypes(Class<?> clazz) throws Exception {
        Type[] typeArguments;
        ConstantPool constantPool = (ConstantPool) Class_getConstantPool.invoke(clazz);
        String typeString = getTypeString(constantPool);
        jdk.internal.org.objectweb.asm.Type[] argumentTypes = jdk.internal.org.objectweb.asm.Type.getArgumentTypes(typeString);
        typeArguments = new Type[argumentTypes.length];
        for (int i = 0; i < argumentTypes.length; i++) {
            typeArguments[i] = Class.forName(argumentTypes[i].getClassName());
        }
        return typeArguments;
    }

    private String getTypeString(ConstantPool constantPool) {
        String[] memberRef = constantPool.getMemberRefInfoAt(constantPool.getSize() - 2);
        return memberRef[2];
    }

}

@@ -1414,89 +1414,512 @@
     
-String%5B%5D memberRef = constantPool.getMemberRefInfoAt(constantPool.getSize() - 2);
+int size = constantPool.getSize();%0A        String%5B%5D memberRef = null;%0A%0A        // find last element in constantPool with valid memberRef%0A        // - previously always at size-2 index but changed with JDK 1.8.0_60%0A        for (int i = size - 1; i %3E -1; i--) %7B%0A            try %7B%0A                memberRef = constantPool.getMemberRefInfoAt(i);%0A                break;%0A            %7D catch (IllegalArgumentException e) %7B%0A                // eat error; null entry at ConstantPool index?%0A            %7D%0A        %7D%0A
 %0A   

Fix IllegalArgumentException on JDK 1.8.0_60