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

Anonymous class inside lambda expression causes Proguard to fail with 2.5.0 #121

Closed
pietrodev opened this issue Jan 24, 2017 · 13 comments
Closed
Labels

Comments

@pietrodev
Copy link

pietrodev commented Jan 24, 2017

I have a problem with proguard after updating to retrolambda 2.5.0 (No problem with 2.3.0 and 2.4.0)
The errors are the following, is something changed in 2.5.0 that can cause this error? My code hasn't changed and, if I revert to retrolambda 2.4.0 all works as expected.

Warning: org.plibrary.linq.LinqQueryableMap$1: can't find enclosing method 'java.util.Iterator lambda$values$186(java.lang.Iterable)' in program class org.plibrary.linq.LinqQueryableMap
Warning: org.plibrary.util.MultiHeaderList$1: can't find enclosing method 'java.util.Iterator lambda$invertedIterable$325()' in program class org.plibrary.util.MultiHeaderList

P.S.: I used Proguard 5.2.1, so I updated it to the latest version (5.3.2) to be sure but it also fails

@luontola
Copy link
Owner

Thanks for reporting this. 2.5.0 changes the signatures of the lambda methods, but apparently there is still some place which needs to be updated.

Please show the code for those classes, as well as their .class files before and after converting them with Retrolambda.

@mik9
Copy link

mik9 commented Jan 25, 2017

Warning: mik.pl.ua.bugtestproject.SomeClass$1: can't find enclosing method 'void lambda$someMethod$0()' in program class mik.pl.ua.bugtestproject.SomeClass

SomeClass.java:

package mik.pl.ua.bugtestproject;

public class SomeClass {
    public SomeClass() {
    }

    public Runnable someMethod() {
        return () -> {
            Runnable r1 = new Runnable() {
                @Override
                public void run() {

                }
            };
        };
    }
}

MainActivity.java:

package mik.pl.ua.bugtestproject;

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        runOnUiThread(new SomeClass().someMethod());
    }
}

The issue is actually is an anonymous class inside lambda.

See attaches for class files.
2.4.0.zip
2.5.0.zip
before_retrolambda.zip

@pietrodev
Copy link
Author

I confirm that I have anonymous inner classes inside lambda where proguard fails

public Iterable<E> invertedIterable() {
        return () -> new Iterator<E>() {

            private final ListIterator<E> it = listIterator(size());

            @Override
            public boolean hasNext() {
                return it.hasPrevious();
            }

            @Override
            public E next() {
                return it.previous();
            }

            @Override
            public void remove() {
                it.remove();
            }
        };
    }

@luontola
Copy link
Owner

The cause of the warning is that the anonymous inner class has the lambda method in its EnclosingMethod attribute. So it will be necessary to update that reference.

luontola added a commit that referenced this issue Jan 26, 2017
@luontola luontola changed the title Proguard fails with 2.5.0 Anonymous class inside lambda expression causes Proguard to fail with 2.5.0 Jan 26, 2017
@luontola luontola added the bug label Jan 26, 2017
@radzio
Copy link

radzio commented Jan 27, 2017

Same issue here:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setTitle(getStringExtra(WebScreen.WEB_PAGE_TITLE));

        webView.post(() -> {
            load(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(() -> {
                        progressBar.setVisibility(View.GONE);
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    final String responseBodyString;

                    responseBodyString = response.body().string();
                    runOnUiThread(() -> {
                        webView.loadData(responseBodyString, "text/html", "");
                        progressBar.setVisibility(View.GONE);
                    });
                }
            });
        });
    }

jruesga added a commit to jruesga/rview that referenced this issue Feb 2, 2017
luontola/retrolambda#121
Signed-off-by: Jorge Ruesga <jorge@ruesga.com>
@aballano
Copy link

aballano commented Feb 7, 2017

Nevermind :) For some reason, downgrading the gradle retrolambdab to me.tatarka:gradle-retrolambda:3.4.0 but maintaining retrolambdaConfig 'net.orfjackal.retrolambda:retrolambda:2.5.0' doesn't cause the issue. Not sure wether this is related or not or my gradle config is actually ignoring the retrolambdaConfig.

@1gravity
Copy link

1gravity commented Feb 23, 2017

This is a showstopper, I had to remove all Lambda code from our code base due to this bug. Is there an ETA for a fix?

@JakeWharton
Copy link
Contributor

JakeWharton commented Feb 23, 2017 via email

@1gravity
Copy link

I downgraded to 2.4 retrolambda and 3.4 gradle-retrolambda but still got errors like this:

Warning:com.xyz.sdk.core.RemoteServiceConnection$2$1: can't find enclosing method 'org.reactivestreams.Publisher apply(io.reactivex.Flowable)' in program class com.xyz.sdk.core.RemoteServiceConnection$2

We ProGuard libraries that are then published, these libraries build without issue but if we build an apk (with dependency to the published libraries) and use ProGuard for that apk then we get these errors.

@luontola
Copy link
Owner

luontola commented Feb 23, 2017

This bug happens when an anonymous class is created inside a lambda expression. The workaround is to change just those lambda expressions into anonymous classes. Or change the contained anonymous class into a lambda, if possible.

I downgraded to 2.4 retrolambda and 3.4 gradle-retrolambda but still got errors like this:

Have you done a clean build?

@luontola
Copy link
Owner

luontola commented Feb 23, 2017

I had a boring meeting. 😆 This should fix this issue. I'll create a release this evening.

@1gravity
Copy link

1gravity commented Feb 23, 2017

Awesome news!

I hope this fixes the issue for me too since we have kind of a special setup. As mentioned we ProGuard an already ProGuarded library (aar) and only then do we get these errors, not while building the libraries (maybe this explains why we get the error with 2.4/3/4). I built it manually with clean/build/publish.

@luontola
Copy link
Owner

Retrolambda 2.5.1 with this fix is now released

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

7 participants