Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong lambda signature calculated #11

Closed
danieldietrich opened this issue Aug 22, 2014 · 3 comments
Closed

Wrong lambda signature calculated #11

danieldietrich opened this issue Aug 22, 2014 · 3 comments
Labels

Comments

@danieldietrich
Copy link
Member

Given a function of type Function<T, R> and a derived function

final SerializableFunction<T, R> lambda = t -> function.apply(t);

the result of Lambdas.getLambdaSignature(lambda) should be (Function) -> R but actually is (Function, Object) -> Object.

@danieldietrich
Copy link
Member Author

@danieldietrich
Copy link
Member Author

getImplMethodSignature() does only work in simple cases (see javaslang.lambda.Lambdas)

@danieldietrich
Copy link
Member Author

Constraint: The lambda has to be Serializable. Here is the test code that shows, that the generic types are erased:

public class Test {

    public static void main(String[] args) throws Throwable {

        final Function<Integer, String> f = i -> String.valueOf(i + 1);

        System.out.println("f.class: " + f.getClass());
        System.out.println("f.class.methods: " + Strings.toString(f.getClass().getMethods()));

        final SerializableFunction<Integer, String> lambda = t -> f.apply(t);
        final SerializedLambda serializedLambda = Lambdas.getSerializedLambda(lambda).get();

        final Class<?> refc = Class.forName(serializedLambda.getFunctionalInterfaceClass().replaceAll("/", "\\."));
        final String name = serializedLambda.getFunctionalInterfaceMethodName();
        final MethodType methodType = MethodType.fromMethodDescriptorString(
                serializedLambda.getFunctionalInterfaceMethodSignature(), lambda.getClass().getClassLoader());

        final MethodHandles.Lookup lookup = MethodHandles.lookup();
        final MethodHandle methodHandle = lookup.findVirtual(refc, name, methodType);

        System.out.println("SERIALIZED LAMBDA: " + serializedLambda);
        System.out.println("METHOD TYPE: " + methodType);
        System.out.println("METHOD HANDLE: " + methodHandle);

        //      final MethodHandle bound = methodHandle.bindTo(lambda);
        //      System.out.println("BOUND METHOD HANDLE: " + bound);
        //
        //      final Object o = bound.invoke(1);
        //      System.out.println("f(1): " + o);

        final MethodHandleInfo info = lookup.revealDirect(methodHandle);
        System.out.println("METHOD HANDLE INFO: " + info);
    }
}

The main problem with respect to this bug is, that captured variables are part of the signature of the generated runtime lambda. I.e. the signature of the following lambda is (Function, Object) -> Object instead of (Integer) -> String:

final SerializableFunction<Integer, String> lambda = t -> f.apply(t);

I will investigate, how to create a SerializedLambda instead to keep the correct signature of the underlying Function f.

@danieldietrich danieldietrich changed the title [lambda] Wrong lambda signature calculated Wrong lambda signature calculated Oct 4, 2014
ruslansennov added a commit to ruslansennov/vavr that referenced this issue Jul 30, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant