gradle-retrolambda
gradle-retrolambda copied to clipboard
Make gradle-retrolambda work with the new Jack & Jill compiler
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.
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.
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?
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?
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.
"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).
@orfjackal Let us know, if you investigate that possibility or if you need some help with testing.
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 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.
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.
@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.
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.
Any luck on this front?
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 .
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:
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,
Done
@evant will you stop work on retrolambda in view of new jack features?
Possibly, no plans right now as jack still isn't quite there yet. (For example annotation processors aren't supported from gradle)
@hzsweers hi!
BTW: Now jack supports annotations processors with gradle annotationProcessor
woohoo
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 why not? Does jackOptions
not work for library projects?
No, currently Jack is not supported for Android Library Projects, and you get an error if you jackOptions
in a library project.