How to run JavaExec with out compile - gradle

I run a gradle javaexec in build.gradle
task main(type: JavaExec) {
main = 'com.gtan.Application'
classpath = sourceSets.main.runtimeClasspath
}
this is the output result:
:compileJava UP-TO-DATE
:compileScala UP-TO-DATE
:processResources UP-TO-DATE
:classes UP-TO-DATE
:main
i want run this javaexec without compile tasks. like:
:main
what should i do ?

When you set up the classpath as the runtime classpath from the main sourceSet, you're telling Gradle that your task depends on the output from the main sourceSet. So, it will compile the main source set first, in order to ensure that the classpath is correctly set up for your JavaExec task.
The answer to your question depends on where the com.gtan.Application class is, and what classpath the application is expecting. If this class resides in the local project, under src/main/java, you won't be able to get rid of compilation, because Gradle must compile this class in order to execute it.
If the class lives in a JAR that your build depends on, for example:
dependencies {
runtime 'com.gtan:this-example-has-what-to-run:1.0.0'
}
Then, you can change your task definition to:
task main(type: JavaExec) {
main = 'com.gtan.Application'
classpath = configurations.runtime
}
By setting the classpath to a configuration, Gradle does not need to perform any compilation, and you get:
$ ./gradlew main
:main

Related

Why won't gradle jar build a jar that gradle build does?

In my Gradle project, I define an additional sourceSet.
sourceSets {
sample {
java {
srcDir 'sample/java'
}
compileClasspath += sourceSets.main.output + sourceSets.main.compileClasspath
}
}
I then add a task:
task sampleJar(type: Jar) {
classifier 'sample'
from sourceSets.sample.output
}
artifacts {
archives sampleJar
}
If I do > gradle build the additional jar file builds from the additional source set. However, if I do > gradle jar, it doesn't. any reason why?
When I go through the output messages, I see:
gradle build has sampleJar in the Tasks to be executed:
but
gradle jar doesn't.
But unsure as to why?
Because jar is just the task that assembles the main jar file.
build, on the other hand, is the top-level life-cycle task, which depends on assemble. And assemble is documented as
Depends on: jar, and all other tasks that create artifacts attached to the archives configuration.
Since your sampleJar pecisely creates an artifact attached to the archives configuration, assemble, and thus build depends on it.

Calling Gradle task for only one subproject

How do I configure subprojects for Gradle and run a Gradle task from the build.gradle only for the current directory I'm executing the task from?
For example, suppose I have two projects in a parent folder:
root-project
project-1
project-2
build.gradle
settings.gradle
I have project 1 and 2 included in the settings.gradle file:
include(
'project-1',
'project-2'
)
I have a task configured in the build.gradle file that I would like to call. I've nested the tasks within a subprojects{} block:
subprojects {
...
task check(type: JavaExec) {
main = MAIN_CLASS
classpath = sourceSets.main.runtimeClasspath
}
...
}
However, the build.gradle is run for all subprojects that way.
How can I define all possible subprojects but only call a Gradle task for the current project I'm executing from (i.e., avoid calling the task for all subprojects)? I would like to do this with the current task name only (e.g., gradle check).
Invoking the task in a single project with gradle check is not possible.
You have two options:
Leverage the model Gradle proposes, where tasks can be prefixed by the project name in a multi project build which removes the need to navigate to subprojects.
Which means invoking gradle :project-1:check or gradle :project-2:check depending on which task you want to run.
Define the tasks to have different name in each subprojects. See task rules on how to define tasks with dynamic names.
Which means invoking gradle check1 or gradle check2

Gradle does not import groovy class when running task

I have a gradle (1.8) project with 2 classes A and B where B import A. Both files are under /foo/bar/ package (myProjectFolder/test/foo/bar folder).
A.groovy class
package foo.bar
import org.junit.Test;
public class ATest{
#Test
public void run() {
System.out.println("CLASS A");
}
}
B.groovy class
package foo.bar
import org.junit.Test;
public class BTest{
#Test
public void run() {
ATest a = new ATest();
a.run();
System.out.println("CLASS B");
}
}
build.gradle
apply plugin: "groovy"
apply plugin: "java"
repositories {
mavenCentral()
}
dependencies {
groovy group: "org.codehaus.groovy", name:"groovy-all", version: "1.8.6"
testCompile "junit:junit:4.10"
}
test {
testLogging.showStandardStreams = true
}
sourceSets {
test { groovy {
srcDir 'test/foo/bar'
} }
}
buildscript {
repositories { mavenCentral() }
}
configurations{
addToClassLoader
}
dependencies {
addToClassLoader "junit:junit:4.10"
}
URLClassLoader loader = GroovyObject.class.classLoader
configurations.addToClassLoader.each {File file ->
loader.addURL(file.toURL())
}
task runA << {
new GroovyShell().run(file('test/foo/bar/ATest.groovy'));
}
task runB << {
new GroovyShell().run(file('test/foo/bar/BTest.groovy'));
}
Output console for gradle clean -Dtest.single=A test
[root#vm1]# gradle clean -Dtest.single=A test
The groovy configuration has been deprecated and is scheduled to be removed in Gradle 2.0. Typically, usages of 'groovy' can simply be replaced with 'compile'. In some cases, it may be necessary to additionally configure the 'groovyClasspath' property of GroovyCompile and Groovydoc tasks.
:clean
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources
:classes
:compileTestJava UP-TO-DATE
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test
foo.bar.ATest > run STANDARD_OUT
CLASS A
BUILD SUCCESSFUL
Total time: 13.205 secs
Output console for gradle clean -Dtest.single=B test
[root#vm1]# gradle clean -Dtest.single=B test
The groovy configuration has been deprecated and is scheduled to be removed in Gradle 2.0. Typically, usages of 'groovy' can simply be replaced with 'compile'. In some cases, it may be necessary to additionally configure the 'groovyClasspath' property of GroovyCompile and Groovydoc tasks.
:clean
:compileJava UP-TO-DATE
:compileGroovy UP-TO-DATE
:processResources
:classes
:compileTestJava UP-TO-DATE
:compileTestGroovy
:processTestResources UP-TO-DATE
:testClasses
:test
foo.bar.BTest > run STANDARD_OUT
CLASS A
CLASS B
BUILD SUCCESSFUL
Total time: 12.218 secs
Output console for gradle -q runA -i
[root#vm1]# gradle -q runA -i
Starting Build
Settings evaluated using empty settings script.
Projects loaded. Root project using build file '/opt/myProject/build.gradle'.
Included projects: [root project 'myProject']
Evaluating root project 'myProject' using build file '/opt/myProject/build.gradle'.
Starting file lock listener thread.
The groovy configuration has been deprecated and is scheduled to be removed in Gradle 2.0. Typically, usages of 'groovy' can simply be replaced with 'compile'. In some cases, it may be necessary to additionally configure the 'groovyClasspath' property of GroovyCompile and Groovydoc tasks.
All projects evaluated.
Selected primary task 'runA'
Tasks to be executed: [task ':runA']
:runA (Thread[main,5,main]) started.
:runA
Executing task ':runA' (up-to-date check took 0.001 secs) due to:
Task has not declared any outputs.
CLASS A
JUnit 4 Runner, Tests: 1, Failures: 0, Time: 63
:runA (Thread[main,5,main]) completed. Took 0.739 secs.
BUILD SUCCESSFUL
Total time: 7.826 secs
Output console for gradle -q runB -i <-- THIS EXECUTION FAILS and I don't know why.
[root#vm1]# gradle -q runB -i
Starting Build
Settings evaluated using empty settings script.
Projects loaded. Root project using build file '/opt/myProject/build.gradle'.
Included projects: [root project 'myProject']
Evaluating root project 'myProject' using build file '/opt/myProject/build.gradle'.
Starting file lock listener thread.
The groovy configuration has been deprecated and is scheduled to be removed in Gradle 2.0. Typically, usages of 'groovy' can simply be replaced with 'compile'. In some cases, it may be necessary to additionally configure the 'groovyClasspath' property of GroovyCompile and Groovydoc tasks.
All projects evaluated.
Selected primary task 'runB'
Tasks to be executed: [task ':runB']
:runB (Thread[main,5,main]) started.
:runB
Executing task ':runB' (up-to-date check took 0.001 secs) due to:
Task has not declared any outputs.
:runB FAILED
:runB (Thread[main,5,main]) completed. Took 0.237 secs.
FAILURE: Build failed with an exception.
* Where:
Build file '/opt/myProject/build.gradle' line: 46
* What went wrong:
Execution failed for task ':runB'.
> startup failed:
/opt/myProject/test/foo/bar/BTest.groovy: 8: unable to resolve class ATest
# line 8, column 9.
ATest a = new ATest();
^
/opt/myProject/test/foo/bar/BTest.groovy: 8: unable to resolve class ATest
# line 8, column 13.
ATest a = new ATest();
^
2 errors
* Try:
Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output.
BUILD FAILED
Total time: 7.872 secs
So, what am I missing to run the task runB correctly?
Note: the premise of the question is based on a truly unorthodox use-case, which should be corrected. That said, I can explain the behaviour that is observed.
When the command-line specifies the test task, then ~/build/classes/test is added to the classpath. In the case of running the runB task, it is not. So BTest.groovy can't find ATest.
To correct it (only as an illustration, not as a suggestion for 'real' code), consider:
// don't do this in a real project!
task runB(dependsOn: 'compileTestGroovy') << {
def testDirURL = new File("${projectDir}/build/classes/test").toURL()
loader.addURL(testDirURL)
new GroovyShell(loader).run(file('test/foo/bar/BTest.groovy'))
}
Now, runB requires that the Groovy test code is compiled, and then manually (!?) adds it to the classloader used by GroovyShell.

Gradle uploadArchives task invoked for module even though explicitly not configured

I have a Java Gradle 2.14.1 project with a few subprojects: a, b, c and no. no is 'special' as it doesn't contain anything in src/main/java, it just has some e2e tests using all the modules. I want to apply the maven plugin to a, b and c, but not to no. Here is my code (in the form of a Bash session; please ignore the fact there is no code - it is the simplest thing which reproduces my issue):
maven-test $ find .
.
./a
./b
./build.gradle
./c
./gradle
./gradle/wrapper
./gradle/wrapper/gradle-wrapper.jar
./gradle/wrapper/gradle-wrapper.properties
./gradle.properties
./gradlew
./gradlew.bat
./no
./no/build.gradle
./settings.gradle
maven-test $ cat settings.gradle
rootProject.name = 'maven-test'
include ':a'
include ':b'
include ':c'
include ':no'
maven-test $ cat build.gradle
subprojects {
apply plugin: 'java'
if (it != project(':no')) {
println 'applying maven for ' + it
apply plugin: 'maven'
uploadArchives {
repositories {
mavenDeployer {
repository(url: "file://build")
}
}
}
} else {
println 'not applying maven for ' + it
}
defaultTasks = ['clean', 'build']
afterEvaluate { project ->
println("================ $project.path tasks:")
project.tasks.each { task ->
println(" $task.name")
}
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.14.1'
}
maven-test $ cat no/build.gradle
jar.enabled = false
I.e. the no/build.gradle file disables the jar task (as there is nothing to jar). The main build.gradle file configures the java and maven plugins, but the maven plugin is explicitly omitted from the no module. Also, there is some debugging output added to see what is going on.
Here is the output (a bit chatty, I hope it is Ok):
maven-test $ ./gradlew clean uploadArchives
applying maven for project ':a'
applying maven for project ':b'
applying maven for project ':c'
not applying maven for project ':no'
================ :a tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :b tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :c tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
install
jar
javadoc
processResources
processTestResources
test
testClasses
uploadArchives
================ :no tasks:
assemble
build
buildDependents
buildNeeded
check
classes
clean
compileJava
compileTestJava
jar
javadoc
processResources
processTestResources
test
testClasses
:a:clean
:b:clean
:c:clean
:no:clean
:a:compileJava UP-TO-DATE
:a:processResources UP-TO-DATE
:a:classes UP-TO-DATE
:a:jar
:a:uploadArchives
:b:compileJava UP-TO-DATE
:b:processResources UP-TO-DATE
:b:classes UP-TO-DATE
:b:jar
:b:uploadArchives
:c:compileJava UP-TO-DATE
:c:processResources UP-TO-DATE
:c:classes UP-TO-DATE
:c:jar
:c:uploadArchives
:no:compileJava UP-TO-DATE
:no:processResources UP-TO-DATE
:no:classes UP-TO-DATE
:no:jar SKIPPED
:no:uploadArchives FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':no:uploadArchives'.
> Could not publish configuration 'archives'
> Cannot publish artifact 'no.jar (com.test:no:0.1.0-SNAPSHOT)' (/Users/wujek/Development/IdeaProjects/maven-test/no/build/libs/no-0.1.0-SNAPSHOT.jar) as it does not exist.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 1.145 secs
What is interesting is: the output says the maven plugin is not configured for the no module (not applying maven for project :no), the uploadArchives task is not listed for the :no module, but in the Gradle output is still says this task is invoked and it fails. I can also invoke this 'phantom' task directly using ./gradlew :no:uploadArchives and it fails the same way instead of telling me the task is missing.
What is wrong with my configuration?

Gradle plugin task ordering

What I have?
Java source file with Main class (MainApp)
gradle build script
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
So when I do gradle run, it executes main method and everything works just perfectly.
C:\tmp\gradle-fun>gradle run
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
BUILD SUCCESSFUL
What I want to do?
Now I was wondering about clean task (common build tasks) to clean the build directory before run task executes.
There is reason behind that, I want to make sure that every time gradle should compile the java files and all .class file should be refreshed (its some requirement)
What I have tried?
Added a wrapper task which executes clean task and run task in order.
apply plugin: 'application'
mainClassName = "MainApp"
sourceSets.main.java.srcDirs = ['.']
task exec(dependsOn: ['clean', 'run'])
So when I run gradle exec, it does it job properly. However I feel that its patch work when you have extra tasks just for ordering execution.
C:\tmp\gradle-fun>gradle run
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:run
Hello MainApp !!
:exec
BUILD SUCCESSFUL
What I would like to know?
Is there any way to avoid writing wrapper task and do some Gradle magic to achieve the requirement?
Just have the run task depend on clean. This will ensure your project is cleaned before every run. If you want to be more specific in regards to your use case, you can simply clean the compileJava task.
run.dependsOn 'cleanCompileJava'
Edit: To avoid deleting your classes before the run add:
classes.mustRunAfter 'cleanCompileJava'
You could create your own task, with clean and run as dependencies:
task cleanRun(dependsOn: [clean, run])
Or, you could follow Mark Vieira's answer and change the wiring:
run.dependsOn 'clean'
classes.mustRunAfter 'clean'
The second line makes sure that it doesn't clean the compiled classes.
Hope this helps =)

Resources