Run task before compilation using Android Gradle plugin
Solution 1
The proper way to run a task before Java compilation on Android is to make a compilation task for each variant depend on your task.
afterEvaluate {
android.applicationVariants.all { variant ->
variant.javaCompiler.dependsOn(generateSources)
}
}
Solution 2
Apparently, the android
plugin doesn't add a compileJava
task (like the java
plugin would). You can check which tasks are available with gradle tasks --all
, and pick the right one for your (otherwise correct) dependency declaration.
EDIT:
Apparently, the android
plugin defers creation of tasks in such a way that they can't be accessed eagerly as usual. One way to overcome this problem is to defer access until the end of the configuration phase:
gradle.projectsEvaluated {
compileJava.dependsOn(generateSources)
}
Chances are that there is a more idiomatic way to solve your use case, but quickly browsing the Android plugin docs I couldn't find one.
Solution 3
You can see task execution in terminal running task for example gradle assemble
. Try this one, it is started practically before anything.
android {
...
gradle.projectsEvaluated {
preBuild.dependsOn(generateSources)
}
...
}
Edit, this may not work in Android Studio, as the Android Gradle DSL does not have a projectsEvaluated
method.
Solution 4
Try this:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.4.1'
}
}
apply plugin: 'android'
android {
buildToolsVersion "17.0.0"
compileSdkVersion 17
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
}
task generateSources {
def script = "python GenerateSources.py".execute()
script.in.eachLine {line -> println line}
script.err.eachLine {line -> println "ERROR: " + line}
script.waitFor()
}
project.afterEvaluate {
preBuild.dependsOn generateSources
}
clean.dependsOn generateSources
clean.mustRunAfter generateSources
The last two lines are optional - they will invoke the "generateSources" task when executing a gradle clean
Michael
Updated on July 09, 2022Comments
-
Michael almost 2 years
I have a very simple
build.gradle
file with the following content:buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:0.4.1' } } apply plugin: 'android' android { buildToolsVersion "17.0.0" compileSdkVersion 17 sourceSets { main { manifest.srcFile 'AndroidManifest.xml' res.srcDirs = ['res'] assets.srcDirs = ['assets'] } } } task generateSources { doFirst { def script = "python GenerateSources.py".execute() script.in.eachLine {line -> println line} script.err.eachLine {line -> println "ERROR: " + line} script.waitFor() } }
What I want is to run
generateSources
task before java compilation is started. I found several solutions how to do that, likecompileJava.dependsOn("generateSources")
, but unfortunately they give an error:A problem occurred evaluating root project 'Android'. > Could not find property 'compileJava' on root project 'Android'.
I don't know Gradle and can't understand what's wrong with this code. So I would like to know how I can fix this error.
-
Peter Niederwieser about 11 yearsWhat is it that doesn't work, and what's the exact error message?
-
Michael about 11 yearsThe problem is the same as before:
Could not find property 'compileDebug' on root project 'Android'.
-
Peter Niederwieser about 11 yearsAnd you verified that
compileDebug
exists? Doesgradle compileDebug
work? Did you add the dependency declaration at the bottom of the build script? You can also trytasks.compileDebug
, but it shouldn't make a difference. -
Michael about 11 years
gradle compileDebug
works fine. At the bottom of the file I addedcompileDebug.dependsOn("generateSources")
. When I writetasks.compileDebug
instead ofcompileDebug
gradle gives me an errorCould not find property 'compileDebug' on task set.
-
Peter Niederwieser about 11 yearsBrowsing the Android plugin docs, I realized that it works quite differently from most other plugins. Does
gradle.projectsEvaluated { tasks.compileDebug.dependsOn(generateSources) }
work? Probably there's a more idiomatic way though. -
Michael about 11 yearsYeah, seems it works! Could you please add it to the answer and explain what it means?
-
slott over 10 yearsAwesome - have been at this for days now not understanding why the usual dependsOn failed for the pre defined tasks. Now I can finally add a dependency to the connectedCheck.
-
Dhrupal over 10 yearsHello Peter Niederwieser, it giving me below error. Could not find property 'compileJava' on com.android.build.gradle.AppExtension_Decorated@44b35022.
-
ento about 10 yearsThe task name seems to have changed to
compileDebugJava
. -
treesAreEverywhere almost 10 yearsI've got a task that needs to run before the Android build. Task copies a jar file into the libs directory. Somehow, this happends too late for the Android build. My android build always fails the first time after a clean. Then the second time it works ( since the jar file is there then). How do run the task that copies the jar file soon enough?
-
treesAreEverywhere almost 10 years@PeterNiederwieser any chance you can update your answer? It's seems to be quite out of date. (Sorry if this sounds a bit rude, it's not meant that way)
-
Peter Niederwieser almost 10 yearsWhy is it out of date?
-
Greg Ennis almost 10 yearsWell, your answer still says "compileJava.dependsOn(...)" which doesnt work, as discussed in comments.
-
IgorGanapolsky almost 8 yearsWhere are you calling your custom task here?
-
Michael almost 8 years
generateSources
is the custom task. AndjavaCompiler
tasks becomes dependent ongenerateSources
. -
Martin Zeitler almost 8 years
./gradlew tasks --all
in the project directory also shows the task's description. -
IgorGanapolsky almost 8 yearsWhat? I get an error: Could not find property 'preBuild' on root project
-
IgorGanapolsky almost 8 yearsI get an error: Could not find property 'android' on root project
-
IgorGanapolsky almost 8 yearsI get an error: Could not find property 'preBuild' on project ':app'
-
Michael almost 8 yearsYou have to apply the Android plugin before this code.
-
Henadzi Rabkin almost 8 yearsSo, probably it doesn't exists now on newer versions of Gradle
-
IgorGanapolsky almost 8 yearsDid it ever exist in Android Studio? Or were you generally speaking about Gradle...
-
Henadzi Rabkin almost 8 yearsIt was used in one of my projects Igor
-
Merk over 7 years@IgorGanapolsky just put prebuild.dependsOn('someTask') within the android { } block, works like a charm. No need to invoke projectsEvaluated.
-
Compaq LE2202x almost 7 years@Michael how do you do that? I'm using Android Studio
-
Michael almost 7 yearsYou just have to put this code into your
build.gradle
file. -
Compaq LE2202x almost 7 years@Michael How do I do this for multiple tasks?
-
Michael almost 7 yearsYou can call
variant.javaCompiler.dependsOn(taskName)
for every task. Another approach is to have a chain of task and callvariant.javaCompiler.dependsOn(taskName)
for the root one. -
ottago about 6 yearsThis is bad since it will run for every invocation. Including things like clean which probably isn't what you want. Depending on what it does it could trigger uptodate checks to do more things.
-
Shubham AgaRwal over 5 yearsAny suggestion who can get build type related info in Gradle task 'generateSources'
-
Khongor Bayarsaikhan over 4 years
variant.javaCompiler
is now obsolete, you should usevariant.javaCompileProvider.get()
-
lasec0203 about 4 yearstsk...tsk..spent hours struggling with getting a task to run because I was putting related code ouside of the android {} block
-
Henadzi Rabkin about 4 years@lasec0203 thanks for pointing this out. I have made an appropriate edit,