Gradle: Task 'run' not found in root project - gradle

I'm trying to use the task 'run' in gradle and it seems that it doesn't exist in my project.
When I type in terminal:
$ gradle run
I get the error message:
FAILURE: Build failed with an exception.
What went wrong: Task 'run' not found in root project 'NA'.
I also built the project again, got "BUILD SUCCESSFUL", and it still didn't help me to commit the 'run' task.
How can I make 'run' task be useful again?

You shouldn't need to manually create a task for run. If it's missing, it means there is something wrong with your build.gradle
In my case, my plugins was missing id 'application' and I didn't have a mainClassName declared at the end of the file. This is what my build.gradle looked like after run became an available task again:
plugins {
id 'java-library'
id 'application'
}
repositories {
jcenter()
}
dependencies {
api 'org.apache.commons:commons-math3:3.6.1'
implementation 'com.google.guava:guava:27.0.1-jre'
testImplementation 'junit:junit:4.12'
}
mainClassName = 'demo.App'

If you don't define a task called run, there is no task called run, so you cannot call a task called run. Either define a task called run that does what you want, or use some plugin that adds a task called run that does what you want. For example the application plugin adds a task called run.
As you said "useful again" you can also track back what you changed from where it was working to where it it not working anymore and then undo it.

check the directory from which you run the build, it should be the same in which the build.gradle file is located

Related

how to execute 'gradle build' command from gradle.build script

I want to execute a gradle build command from build.gradle file.
build.gradle file
apply plugin: 'java'
apply plugin: 'application'
task me{
//Can we perform gradle build command here.
}
Question:
Can we perform gradle build command inside task me, similarly like we do from command prompt(screenshot attached)..?
Note : I am using windows env, please assume I am providing all other statements in build.gradle file.
I am able to build from command prompt by executing
.
I want to execute this task me from command prompt and it should be responsible to call gradle build command.(attached screenshot)
Yes, if you make the task me to a task of type GradleBuild
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.GradleBuild.html
E.g.
task me(type: GradleBuild){
buildFile 'mybuild.gradle' //defaults to build.gradle so not needed
dir 'someDir'
tasks 'clean', 'build'
}
You cannot "call" a Gradle task in a Gradle build.
You might stumble upon the method execute() that each Gradle task has, but this is a purely internal method that must not be used by any build script. Using it will not work properly. It will not ensure the task is run only once, it will not ensure dependency tasks are run before and so on and so on, just don't use it.
Your code snippet is too big for me wanting to interpret it right now to understand what you want to do exactly, but if you want to "call" a Gradle task from another Gradle task, your logic is bogus and should be changed. If you want to run a Gradle task before or after another Gradle task is run, the only supported way is to use dependsOn (before) or finalizedBy (after) and you can not set these properties during execution phase of a task but only during configuration phase.
Well, there is one other way to call a Gradle task from a build script, but this is by using a task of type GradleBuild which would start a complete new and separate build of the project you specify which is most often not the action you really want to do.

Gradle show content of compile configuration of a sub project

Try to show a configuration content of sub project foo:
task foo {
project(':foo').configurations.compile.files.each {
println it.name
}
project(':foo').configurations.compileClasspath.files.each {
println it.name
}
}
Error
* What went wrong:
A problem occurred evaluating project ':foo'.
> Cannot change dependencies of configuration ':foo:compile' after it has been resolved.
I am confused with configurations.compile and configurations.compileClasspath. Are they the same? both are FileCollection?
For current project (not :foo), they contain the same set of files.
Your problem is based on the same technical detail as most of the Gradle problems at StackOverflow: the difference between the configuration phase and the execution phase.
If you define a task (like foo in your example), the code in the following closure does NOT define what the task will do on execution. Instead, it is executed right after the task definition and should be used to configure the task. This is why the code will be executed every time you run Gradle on the project (in the configuration phase). On the other hand, the task in your example will do absolutely nothing when its executed (in the execution phase). Only task actions (defined by the task type), doFirst and doLast closures are executed during execution phase. Also note, that (task) configuration will be done for every task, but only selected tasks (via command line or dependencies) will be executed.
Knowing the above, we can understand the problem in your code: It tries to print the contents of a configuration of a subproject during the configuration phase of the root project. The configuration phase of the subproject, where you add dependencies, comes after the configuration phase of the root project, where you resolve the configuration (which is necessary to show the contents). But you can't add dependencies to configurations that are already resolved.
This means, that your code gets executed, resolves the configuration and prints nothing, because at the moment of execution the configuration is empty. After that, in your subprojects dependencies closure, you are trying to add a dependency to the configuration that is already resolved, which causes the error. Comment out all (compile) dependencies in your subproject foo and the error should disappear.
However, this is not what you want. You want to list the files of the configuration after they have been added. To achieve this, you can easily move your task code to a doLast (or doFirst) closure:
task foo {
doLast {
project(':foo').configurations.compile.files.each {
println it.name
}
}
}
Now, your configuration is resolved in the execution phase of your root project, which comes after the configuration phase of the subproject, so there won't be any problems adding dependencies. Please note, that the task will only be executed if you specify it (e.g. calling gradle foo / gradle build foo or using dependsOn foo on another task which will be executed).
Regarding the difference between the compile and the compileClasspath configuration, you can take a look at the docs of the Gradle Java Plugin, which defines both configurations: Configurations can extend other configurations, which means that they will contain all dependencies the other configuration contains, but can also contain additional dependencies. If you only use compile dependencies, compile and compileClasspath will be the same, but e.g. a compileOnly dependency will only be listed under compileClasspath.

Run task before repositories are added and dependencies are resolved

I'm working on compiling python bindings using gradle.
There is a plugin by linkedin that facilitates that.
They also include a project called the pivy-importer that converts python dependencies into an ivy repository.
I've created a gradle plugin that wraps the pivy-importer so that it can run as a python task.
My repositories are declared like this:
repositories {
pyGradlePyPi()
ivy {
name 'pypi-local' //optional, but nice
url "${project.buildDir.path}/pythonIvy"
layout "pattern", {
ivy "[organisation]/[module]/[revision]/[module]-[revision].ivy"
artifact "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
m2compatible = true
}
}
}
The problem, however, is that the repositories are being loaded before the plugin executes.
The first task that the python task runs is pinRequirements so I was adding my cusom pythonImporter task before that like this:
pinRequirements.dependsOn pythonImporter
However, even when I do that, the console shows that the pythonImporter task is running before but as soon as it tries to assemble the dependencies, it can't find them even though they do exist in the file system.
If you rerun the task again, however, it passes because the first run added the repository to the file system.
TL;DR
I need a way to run a task before dependencies are looked up under using a project's configured repositories are loaded.
I moved the tasks execution to my buildSrc subproject and made the build task depend upon its execution.
This works because the buildSrc project is always evaluated before the rest of the projects so you can do "before build" logic there.

Gradle task at the end of build with a multiproject build

I am attempting to create my own task, that will create a package of all the artifacts generated during my multi-project build.
Currently what I do right is now just:
gradle build createPackage
Which gives output like the following:
:test-utility:compileJava UP-TO-DATE
:test-utility:processResources UP-TO-DATE
...
:test-utility:check UP-TO-DATE
:test-utility:build UP-TO-DATE
Creating Package...
Created.
BUILD SUCCESSFUL
Total time: 4.654 secs
With the createPackage task being:
task createPackage {
println "Creating Package..."
println "Created."
}
However, I would like to simply it by running just one command, so what would the best way to do this and ensure the order stays maintained?
Ideally I would like to call build within the createPackage task or append to the build task with my task.
Ok reading between the lines there are a few things to clear up
1) Your printlns are being run in the configuration phase, not the execution phase. See http://www.gradle.org/docs/current/userguide/build_lifecycle.html for more info.
2) You do not have a single 'build' task. gradle build on the command line will run the 'build' task of each of your subprojects. Your package task would need to depend on all of them. Something like..
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
dependsOn subprojects*.build
}
3) You can be more declarative with gradle - just tell it what you want to package up and it will figure out what it needs to run. For example, you can say that you want to zip up all the jars from your subprojects.
apply plugin: 'java'
evaluationDependsOnChildren()
task createPackage(type:Zip) {
from subprojects*.jar
}
There are plenty of ways. One suggestion is to modify build to depend on createPackage to make sure you can call just gradle build. Then you want to enhance your task and tell what are its inputs (probably those are outputs of some other tasks like jar). Gradle will add these tasks to execution when you run the build and can re-run them based on up-to-date status of each task. This is documented in userguide - http://www.gradle.org/docs/current/userguide/more_about_tasks.html#sec:up_to_date_checks and later in a chapter on custom tasks.

Why is uploadArchives not listed at the tasks list?

i thought uploadArchives is a task which is provided by the java plugin.
In my build.gradle i use the java plugin:
apply plugin: 'java'
But if i invoke gradle tasks on command line, i can't see the uploadArchives task.
Even not with gradle gradle tasks --all
The uploadArchives task is listed in the gradle java plugin documentation
see http://www.gradle.org/java_plugin (table 11).
I use gradle version 1.0-milestone-6.
I can invoke gradle uploadArchives without error, but the task is not listed.
The uploadArchives task is added as a Rule to your build script and not explicitly by name. In the output of "gradle tasks" you should see this line:
Pattern: upload<ConfigurationName>: Assembles and uploads the artifacts belonging to a configuration.
This means, that for each configuration in your build file, an according uploadTask exist. The java plugin adds an configuration named archives to your build script. By adding the configuration "archives" to your build script explicitly by the java plugin, the uploadArchives task is added implicitly too.
There are scenarios, where gradle can't know what tasks need to be materialized by a rule.
E.g.
tasks.addRule("Pattern: ping<ID>") { String taskName ->
if (taskName.startsWith("ping")) {
task(taskName) << {
println "Pinging: " + (taskName - 'ping')
}
}
}
There is no way to figure out which ping tasks should be shown as they are just materialized when triggered from commandline via 'gradle pingServer1 pingServer2 pingServer3'
regards,
René
The uploadArchives task is a part of the maven-plugin. You have to add:
apply plugin: 'maven'

Resources