Closed dbachelder closed 9 years ago
well... just in case this rings anyones bell... I was trying to debug the problem on a new branch. I am able to do a ./gradlew clean :module:assembleDebug
one time after checking out the branch then it fails each subsequent attempt... switching back to the other branch gives me the same behavior.. 1 success.. then failures. I can go back and forth like this ad nauseam.
I'll continue to debug.
So... I finally hacked a version of the plugin together that works consistently again...
I have no idea why this stopped working for us.. but suddenly I need to ensure the -s argument points at a directory that exists... so I did this in RetrolambdaPluginAndroid
around line 82
newJavaCompile.doFirst {
var.javaCompile.options.compilerArgs[-1].mkdirs(); // added this line....
newJavaCompile.options.compilerArgs = var.javaCompile.options.compilerArgs + ["-bootclasspath", "$jarPath/android.jar"]
}
I know this is not the correct answer, so if someone who understands the interplay between the various plugins could enlighten me on what is going wrong and why this hack works, I would appreciate it!
That change only worked for library projects... for our actual apps I needed to change it..
var.javaCompile.options.compilerArgs.find { it instanceof File }?.mkdirs()
Just more brute force... but if the assumption that the only compilerArg that's a File
is the -s
arg for both libraries and apps holds up.. this works. We can now build again with this hack... I would still like to understand what has happened to require this. It seems like android-apt is not being run at the correct time in the phase where it should be to create <module>/build/generated/source/apt/release
This is all becoming clear to me now... I have no idea how this was ever working.
in android-apt we do this:
variant.javaCompile.options.compilerArgs += [
'-processorpath', processorPath,
'-s', aptOutput
]
... snip ...
variant.javaCompile.doFirst {
aptOutput.mkdirs()
}
UPDATE: I had the execution order backwards in my original description of what I ultimately thought the problem was... it's actually this... i think:
var.javaCompile.deleteAllActions()
Which removes the doFirst
that was added by android-apt. @evant why is that done? @hvisser is there any reason not to create the aptOutput dir in afterEvaluate
or somewhere else that is less prone to modifications to the actions on the compile task?
Ah, it looks like others have run into this issue as well:
https://bitbucket.org/hvisser/android-apt/issue/24/source-folders-generated-at-incorrect
Thank you for looking into this, I have attempted to release a fix for the android-apt
plugin but apparently it's not as effective as I had hoped. I've gone through several iterations on how to insert/replace the retrolambda tasks into the java compile sequence, and deleting the original task and creating my own is the best I've come up with so far. I'm aware that deleteAllActions()
deletes the doFirst
as well, but I don't know of any gradle api to only delete the original task action, nor to manually run the doFirst
/doLast
blocks.
Like I commented on the android-apt
issue: creating the directory at project eval time won't work, since it might get deleted when you do a clean
for example. I'm not sure if there's a better way to make sure the directory exists at the time the compile tasks runs...
Thanks @hvisser
@evant I have created a PR with the fix I am now using locally... https://github.com/evant/gradle-retrolambda/pull/66
@evant Wouldn't it be possible to copy the original tasks to the newJavaCompile as well? Or maybe a bit more hacky, invoke the actions in the Task.actions list one by one? doFirst and doLast only manipulate the list of actions if I understand correctly.
Like I said before, I haven't seen any gradle api's that let me do that. If you come up with one I'm missing, I'm all ears.
Something like javaCompile.actions.each { it -> newJavaCompile.doFirst(it) }
Haven't tried it :)
That would include the original javaCompile action which I'm trying to delete! I've looked at actions
before, but their types are all internal, so I don't think I can even reliably switch on it.
Just to note, the way I attempted to fix this in 2.4.1
was to try to make sure android-apt
added it's doFirst
block after retrolmabda
set up the configuration. That way would be called after deleteAllActions()
and still be run. I would like to try to figure out why exactly that is not working as expected.
@evant Oh, sorry, I think I misunderstood what the code was doing then. I assumed there was a JavaCompile task (http://www.gradle.org/docs/current/dsl/org.gradle.api.tasks.compile.JavaCompile.html) that got configured. Does that have actions by default?
Any news about this? I'm still having
Error:Execution failed for task ':app:_compileDebugJava'.
> directory not found: [...] /app/build/generated/source/apt/debug
I'm using retrolambda 2.4.1, applying plugin like this:
apply plugin: 'android-sdk-manager'
apply plugin: 'com.android.application'
apply plugin: 'retrolambda'
apply plugin: 'com.neenbedankt.android-apt'
Of course, I can manually create the folder locally and be able to build, but it will still crash on the remote CI server. Thank you
Sorry, I've been busy this past week. This issue is not easy to solve and it doesn't help that it builds correctly on my machine. If you can give any insight into why the order of modifications (deleteAllActions()
then android-apt
adding it's deleteFirst
block) isn't working correctly on your setup, it would be very helpful.
I'm using Travis as CI. You could try to reproduce the bug on Travis and check a setup that's different than yours.
Reproduced with enroscar's reactive goodies. Sorting order plays no role. If I create apt/debug folder by hand – works with no problems.
apply plugin: 'com.android.application'
apply plugin: 'retrolambda'
apply plugin: 'com.stanfy.android.apt'
Maybe issue is linked with this issue?
@almozavr No, totally unrelated. The issue is that the retrolambda plugin clears the custom actions set on the compile task and there's no real way to get those tasks back. @evant One dirty hack I can think of is to inspect the new JavaCompile task and check the number of actions. Then compare that to the task you are clearing and copy over the extra actions from the old task. From debugging it looks like tasks are added at the front on of the actions list. But it's a gross hack :)
Hi, is there any progress with this?
You can check my sample project to reproduce it: https://github.com/mgrzechocinski/dagger2-example/tree/topic/retrolambda-issue
./gradlew clean assembleDebug
./gradlew clean assembleRelease
Thanks for the sample project, that helped me narrow it down a bit. I think it's because the original javaCompile
task is getting into a state where it thinks it's already up to date and so doesn't run again. See if doing it with --rerun-tasks
once fixes it, at least temporarily.
I've uploaded a SNAPSHOT version that appearers to fix the issue. Can I get some people who are experiencing this to test with the snapshot version?
buildscript {
repositories {
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:2.4.2-SNAPSHOT'
}
}
Important! If you are upgrading a project from an older version, run gradle build --rerun-tasks
. You should only have to do this once.
The SNAPSHOT is working here. +1 kudos :) Thank you
Alright, version 2.5.0 with this fix is released.
Yep, seems like 2.5.0 fixed the issue. Thanks a lot for your support!
Being curious about the change, I reviewed your commit and have one possible hint/question regarding Gradle & overriding standard tasks behaviour.
My previous project had some native code build by NDK. Since standard NDK support was not enough for us, we developed custom NDK task which suited our needs. The only problem we had was to force Gradle to use our task instead of built-into Android plugin. At first, I did it by just creating native task dependent or our, and also make is actions as empty set:
def nativeGradleComplikeNdkTask = "compile${variant.name.capitalize()}Ndk" {
actions = [];
}
nativeGradleComplikeNdkTask.dependsOn(compileNdkLegacy)
I worked perfectly since Gradle plugin v0.13. Unfortunately, keeping set of actions as empty stopped working in v0.13 where Google guys (I guess) introduced some additional behaviour in doFirst/doLast methods. In our case it occurred as output generated by our task was just simply cleared by one of the actions in doFirst/doLast in native gradle tasks. Since native actions set was empty, no *.so file was bundled in final APK.
So how I fixed it? I eventually disabled native task by:
def nativeGradleComplikeNdkTask = "compile${variant.name.capitalize()}Ndk" {
enabled = false;
}
nativeGradleComplikeNdkTask.dependsOn(compileNdkLegacy)
That works like a charm in every version of Android Gradle plugin.
So the question is: in retrolambda case, isn't it better to just disable native compile task and introduce dependent one instead of removing it? Thanks in advance for your comments. I'm just curious about it.
I believe I tried that first and it didn't work correctly, but I can't remember exactly what the issue was.
Edit: I just tried doing var.javaCompile.enabled = false
, and I'm getting the same apt directory not found error. I guess that causes it to disable doFirst/doLast blacks as well?
I've got the same issue with retrolambda version 3.0.1, with version 2.5.0 - works good. Need to reopen this issue.
@ultraon same thing here
Happening here with 'me.tatarka:gradle-retrolambda:3.2.5'
gradle-retrolambda version 2.4.1 / android-apt 1.4 / android gradle (0.14.1) / tools 21.1.0
Suddenly we are seeing strange issues in our build process.. there are no diffs to any gradle files.
However, we now see this:
and this is the order of applied plugins:
Everything was working fine a few hours ago.. and checking out source to yesterday doesn't seem to help. Is anyone else noticing bizarre issues today? Or am I completely nuts? I'm at a bit of a loss at the moment.