gradle-retrolambda icon indicating copy to clipboard operation
gradle-retrolambda copied to clipboard

Make gradle-retrolambda work with the new Jack & Jill compiler

Open cypressious opened this issue 10 years ago • 24 comments

This is probably a bit early, but I guess it doesn't hurt to have an issue to track the state of gradle-retrolambda's compatibility with the new Jack & Jill compiler. This article describes Google's new compiler for Android which is able to compile Java sources directly to dex format. If you're using the Android plugin version 0.14+ you can enable it in your build by adding the following line to the android part:

useJack true

When I did this the Gradle sync failed with the following stacktrace:

* Exception is:org.gradle.api.ProjectConfigurationException: A problem occurred configuring project ':blsAndroid'.
        at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:79)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:74)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:61)
        at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:521)
        at org.gradle.api.internal.project.AbstractProject.evaluate(AbstractProject.java:82)
        at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:31)
        at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:129)
        at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:106)
        at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:86)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:80)
        at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:33)
        at org.gradle.launcher.cli.ExecuteBuildAction.run(ExecuteBuildAction.java:24)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:36)
        at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
        at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:47)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:35)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:24)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.StartStopIfBuildAndStop.execute(StartStopIfBuildAndStop.java:33)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.ReturnResult.execute(ReturnResult.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:71)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:69)
        at org.gradle.util.Swapper.swap(Swapper.java:38)
        at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:69)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:70)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:45)
        at org.gradle.launcher.daemon.server.DaemonStateCoordinator.runCommand(DaemonStateCoordinator.java:258)
        at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy.doBuild(StartBuildOrRespondWithBusy.java:49)
        at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:34)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.HandleCancel.execute(HandleCancel.java:36)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.HandleStop.execute(HandleStop.java:30)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.DaemonHygieneAction.execute(DaemonHygieneAction.java:39)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.CatchAndForwardDaemonFailure.execute(CatchAndForwardDaemonFailure.java:32)
        at org.gradle.launcher.daemon.server.exec.DaemonCommandExecution.proceed(DaemonCommandExecution.java:125)
        at org.gradle.launcher.daemon.server.exec.DefaultDaemonCommandExecuter.executeCommand(DefaultDaemonCommandExecuter.java:52)
        at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.handleCommand(DefaultIncomingConnectionHandler.java:154)
        at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.receiveAndHandleCommand(DefaultIncomingConnectionHandler.java:128)
        at org.gradle.launcher.daemon.server.DefaultIncomingConnectionHandler$ConnectionWorker.run(DefaultIncomingConnectionHandler.java:116)
        at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
Caused by: java.lang.NullPointerException: Cannot get property 'destinationDir'on null object        at me.tatarka.RetrolambdaPluginAndroid$_apply_closure1_closure2.doCall(RetrolambdaPluginAndroid.groovy:66)
        at me.tatarka.RetrolambdaPluginAndroid$_apply_closure1.doCall(RetrolambdaPluginAndroid.groovy:63)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:40)
        at org.gradle.listener.ClosureBackedMethodInvocationDispatch.dispatch(ClosureBackedMethodInvocationDispatch.java:25)
        at org.gradle.listener.BroadcastDispatch.dispatch(BroadcastDispatch.java:83)
        at org.gradle.listener.BroadcastDispatch.dispatch(BroadcastDispatch.java:31)
        at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
        at com.sun.proxy.$Proxy12.afterEvaluate(Unknown Source)
        at org.gradle.configuration.project.LifecycleProjectEvaluator.notifyAfterEvaluate(LifecycleProjectEvaluator.java:67)
        ... 52 more

Since gradle-retrolambda is indispensable to me, I would love to see it work nicely with the new compiler.

cypressious avatar Dec 02 '14 22:12 cypressious

Right, this went though my head as well when I read about that.I can think of one solution (converting your source to class files -> retrolambda -> jill -> jack -> dex) but it would defeat the performance gains you would get with the new compiler.

evant avatar Dec 02 '14 23:12 evant

Would it be possible to only pipe those classes that need conversion through retrolambda and jill and let the rest be taken care of by jack?

cypressious avatar Dec 02 '14 23:12 cypressious

And on a completely different note, would it be possible to hook into jack directly and somehow allow direct translation of Java 8 source code to dex? @orfjackal, any opinions?

cypressious avatar Dec 02 '14 23:12 cypressious

From what I understand, you could not hook into jack directly short of forking it since it doesn't understand java 8 syntax. As for only running classes that need conversion though java 8 -> retrolambda -> jil, that may be doable, though I don't know how hard it would be to dertermine which parts of your code need it. Another aproach would have retrolambda directly produce jyce which would save a step, though I would imagine that would take a significant reworking.

evant avatar Dec 03 '14 02:12 evant

"Javac -> Retrolambda -> Jill" seems like the most feasible possibility. The other option is improving Jack to support Java 8. The article says that Jack is based on the Eclipse compiler, which supports Java 8, so it should have some support for lambdas (the code generation part would need to be changed to generate anonymous classes).

luontola avatar Dec 03 '14 12:12 luontola

@orfjackal Let us know, if you investigate that possibility or if you need some help with testing.

cypressious avatar Dec 04 '14 14:12 cypressious

I looked into the source of jack a bit and it is using a version of ecj that has java 8 support so that's good. It still looks like there would be quite a bit of work in modifying it to support lambdas though, and I'm still on the fence on if it's a good idea. I can push up what I have so far if anyone else is interested.

evant avatar Dec 12 '14 04:12 evant

@evant please do push up what you have. I don't know that I personally could help much, but having it there and available for other developers can only help. You never know when a random compilers guru might stumble along and decide to help :stuck_out_tongue_winking_eye:

Maybe mention something about this in the README as well.

ZacSweers avatar Dec 28 '14 05:12 ZacSweers

Anyone called a "random compilers guru"? Nah, joking. Still, if @evant pushes up some code I can make myself some time to check it out.

mradzinski avatar Jan 02 '15 20:01 mradzinski

@evant please show us what you have done so far, I will try and see if I can make heads or tails of it to contribute.

brcolow avatar Jan 09 '15 06:01 brcolow

Alright, I pushed it to https://github.com/evant/jack-lambda. All I've done so far is remove the java version checks so that instead of complaining about java 8 not being supported, it fails with an internal error.

evant avatar Jan 09 '15 13:01 evant

Any luck on this front?

ZacSweers avatar Jan 24 '15 01:01 ZacSweers

Nothing since the initial commit. I don't really have any experience with compilers. Feel free to take a look if you are so inclined. On Jan 23, 2015 8:30 PM, "Henri Sweers" [email protected] wrote:

Any luck on this front?

— Reply to this email directly or view it on GitHub https://github.com/evant/gradle-retrolambda/issues/71#issuecomment-71293831 .

evant avatar Jan 24 '15 10:01 evant

http://developer.android.com/preview/j8-jack.html Given that this is happening, it would be great if @evant is able to fix this issue :+1:

gaara87 avatar Mar 09 '16 20:03 gaara87

at this point, it seems like there wouldn't be any added benefit to using retrolambda if you use jack. I think you could probably mark this as wontfix,

ZacSweers avatar Mar 09 '16 20:03 ZacSweers

Done

evant avatar Mar 09 '16 21:03 evant

@evant will you stop work on retrolambda in view of new jack features?

IlyaEremin avatar Mar 10 '16 08:03 IlyaEremin

Possibly, no plans right now as jack still isn't quite there yet. (For example annotation processors aren't supported from gradle)

evant avatar Mar 10 '16 14:03 evant

@hzsweers hi!

eolszewski avatar Apr 27 '16 18:04 eolszewski

BTW: Now jack supports annotations processors with gradle annotationProcessor

epool avatar May 27 '16 16:05 epool

woohoo

IlyaEremin avatar May 27 '16 18:05 IlyaEremin

Please note that for now Jack only supports application module. This mean that we can't use Jack on Android Libraries modules, which is still a valid use case for retrolambda.

thibautd avatar Aug 31 '16 13:08 thibautd

@thibautd why not? Does jackOptions not work for library projects?

IlyaEremin avatar Sep 02 '16 07:09 IlyaEremin

No, currently Jack is not supported for Android Library Projects, and you get an error if you jackOptions in a library project.

thibautd avatar Sep 02 '16 07:09 thibautd