ronmamo / reflections

Java runtime metadata analysis
Do What The F*ck You Want To Public License
4.72k stars 701 forks source link

Issue with getMethodUsage with anonymous functions within Java8 Lambda expressions #280

Open ravikgunnam opened 4 years ago

ravikgunnam commented 4 years ago

I am using version: 0.9.12

When I use getMethodUsage with Java 8 Lambdas, getting Can't resolve member named... error.

Here the code snippets and the actual error:

public class LambdaModel {

    private String label;

    public String getLabel() {
    return label;
    }

    public void setLabel(String label) {
    this.label = label;
    }

}

public class LambdaUtil {

    public LambdaModel filterByLabelLambdas() {
    List<LambdaModel> list = new ArrayList<LambdaModel>();
    LambdaModel lambdaModel = list.stream()
        .filter(m -> m.getLabel()
            .equals("sometext"))
        .findAny()
        .get();
    return lambdaModel;

    }

}

public class TestMain {

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

    Reflections reflections = new Reflections(ClasspathHelper.forPackage("my.package"), new MemberUsageScanner());
    reflections.getMethodUsage(LambdaModel.class.getDeclaredMethod("getLabel"));
    }

}

Error:

Exception in thread "main" org.reflections.ReflectionsException: Can't resolve member named my.package.LambdaUtil.lambda$0(my.package.LambdaModel) #11
    at org.reflections.util.Utils.getMembersFromDescriptors(Utils.java:112)
    at org.reflections.Reflections.getMethodUsage(Reflections.java:602)
    at TestMain.main(TestMain.java:22)
Caused by: org.reflections.ReflectionsException: Can't resolve member named 0 for class my.package.LambdaUtil.lambda
    at org.reflections.util.Utils.getMemberFromDescriptor(Utils.java:81)
    at org.reflections.util.Utils.getMembersFromDescriptors(Utils.java:110)
    ... 2 more

Thank you and appreciate any help.

ziqin commented 4 years ago

Probably related to ronmamo/reflections#253.

Liloveyang commented 4 years ago

I also found this problem, there is a potential exception to getMethodUsage, which may not be able to parse this method class with lambda expression!

ravikgunnam commented 4 years ago

Also, if I fix the parsing issue, there is still an underlining issue finding the actual method references within lambda expressions. In the example provided here, the expected result is LamdaUtil#filterByLabelLambdas() , however, it returns LambdaUtil.lamda$1(...

I was wondering if there is a work around for this problem. Thank you very much and appreciate any help.

ziqin commented 4 years ago

I'm also interested in fixing this issue. I think it's better to do some extra work if a lambda expression is encountered and return the expected result, i.e. LamdaUtil#filterByLabelLambdas() in this example.

Liloveyang commented 4 years ago

I'm also interested in fixing this issue.

ziqin commented 4 years ago

I reconsidered the problem about returning the expected result and realized that it involves more decisions to make and is difficult to implement.

Think about these problems: If we choose to return the outer method for lambda expression usage, what should we return for anonymous inner class usage? What should we return for a lambda expression usage in the body of another lambda expression?

In terms of implementation, it is possible to extract the name of the outer method from the synthetic name LambdaUtil.lamda$filterByLabelLambdas$1. However, if filterByLabelLambdas is overloaded, we cannot determine which one actually uses the lambda expression of concern.

rimuln commented 4 years ago

some attempt to solve the lambdas problem is fixed and released in aschoerk/reflections8 that merge my PR. At least all cases where we use it my fix works for it: PR request was merged with this commit (If i'm looking correct) https://github.com/ronmamo/reflections/commit/c5efd259c4ed4e3b00f84cf1b6041a25be078c5f it is said that not all was merged to original reflections. So until this will be fixed we will stay on reflections8 :(