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

[Compiler] Reflection fails due to class file's EnclosingMethod attribute incorrectly pointing to lambda implementation #975

Closed
Marcono1234 opened this issue Apr 16, 2023 · 1 comment · Fixed by #1072
Assignees
Labels
bug Something isn't working
Milestone

Comments

@Marcono1234
Copy link

Marcono1234 commented Apr 16, 2023

Version

Eclipse Compiler 3.33.0
(Maven: org.eclipse.jdt:ecj:3.33.0)

Description

Preconditions:

  • a generic method M of a local class ...
  • contains a lambda expression ...
  • which creates an anonymous class C of a generic class ...
  • which captures a type variable from M

In that case reflection erroneously returns null as type argument for C.
If any of the above is changed, e.g. not using a lambda, or not using a local class, then it looks like this cannot be reproduced.

Have reported this for the Eclipse compiler because the same code seems to work as expected when compiling and running using JDK 17 (though same error occurs with JDK 11, see JDK-8306438). But maybe this is actually a bug in the Java reflection library.

Reproduction steps

  1. Create a file called Test.java with the following content
    import java.lang.reflect.*;
    
    class Test {
        static class Capturing<T> {
            protected Capturing() {
                ParameterizedType paramT = (ParameterizedType) getClass().getGenericSuperclass();
                Type t = paramT.getActualTypeArguments()[0];
    
                if (t instanceof TypeVariable) {
                    System.out.println("Found expected type");
                } else {
                    throw new AssertionError("Unexpected type: " + t);
                }
            }
        }
    
        static void run(Runnable r) {
            r.run();
        }
    
        public static <T> void main(String... args) {
            class Local {
                <M> void runTest() {
                    run(() -> new Capturing<M>() {});
                }
            }
    
            new Local().runTest();
        }
    }
  2. Compile the class with the Eclipse compiler
    java -jar ./ecj-3.33.0.jar -17 ./Test.java
    
  3. Try to run the compiled class using Java 17
    java Test
    ❌ Bug: It fails with AssertionError: Unexpected type: null
@srikanth-sankaran
Copy link
Contributor

I think ECJ emits wrong EnclosingMethod attribute. Javac had a problem in this space and was fixed via https://bugs.openjdk.org/browse/JDK-8215470

@srikanth-sankaran srikanth-sankaran changed the title [Compiler] Reflection returns null for lambda capturing local method type variable [Compiler] Reflection fails due to class file's EnclosingMethod attribute incorrectly pointing to lambda implementation May 18, 2023
srikanth-sankaran added a commit that referenced this issue Jun 8, 2023
…ectly pointing to lambda implementation

Fixes #975
@iloveeclipse iloveeclipse added this to the 4.29 M1 milestone Jun 8, 2023
@iloveeclipse iloveeclipse added the bug Something isn't working label Jun 8, 2023
robstryker pushed a commit to robstryker/eclipse.jdt.core that referenced this issue Jul 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants