How do I replace the default source folders for gradle? - gradle

I am new to Gradle and I have a source code location different than what Gradle expects.
Gradle expects to find the production source code under src/main/java and your test source code under src/main/resources. How do I configure Gradle to a different source code?

You have to add few lines to build.gradle:
To replace the default source folders, you will want to use srcDirs instead, which takes an array of the path.
sourceSets {
main.java.srcDirs = ['src/java']
main.resources.srcDirs = ['src/resources']
}
Another way of doing it is:
sourceSets {
main {
java {
srcDir 'src/java'
}
resources {
srcDir 'src/resources'
}
}
}
The same thing is applicable to test folder too.

Related

How to share common shared folder with multiple test source sets in gradle

My test source structure is as follows:
test
testFunctional
testIntegration
testSupport
The testSupport folder contains common code to be shared among all test folders.
The definition of the source sets in gradle looks like below:
test {
java {
srcDirs = ['src/test/java', 'src/testSupport/java']
}
resources {
srcDirs = ['src/test/resources']
}
}
functionalTest {
java {
srcDirs = ['src/testFunctional/java', 'src/testSupport/java']
}
resources {
srcDirs = ['src/testFunctional/resources']
}
}
integrationTest {
java {
srcDirs = ['src/testIntegration/java', 'src/testSupport/java']
}
resources {
srcDirs = ['src/testIntegration/resources']
}
}
}
IntelliJ currently complains that "Duplicate content roots detected" referring to the fact that the same 'src/testSupport/java' folder is shared among multiple source sets.
Do you have a more elegant solution to achieve sharing code among test folder in gradle without going to a multi-module approach?

How to specify classes output directory for Gradle 4?

Gradle project deprecated 'classesDir' so the previously working method:
sourceSets {
main {
output.classesDir = "myDir"
}
}
should be replaced with something else. Documentation talks about 'output.classesDirs' but this is read-only property.
What is the method to specify custom compilation output directory in Gradle 4.x scripts?
If you are working with java you can do this
apply plugin: 'java'
sourceSets {
main {
// Compiled Java classes should use this directory
java.outputDir = file('myDir')
}
}
See more: https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/SourceSetOutput.html
As per Gradle 6.5.1 docs the java.outputDir property is has been replaced by classesDirectory:
Gradle 6.5.1 docs for SourceDirectorySet
However I think that the destinationDirectory property should be used to read or modify the compiler output dir. So the docs should say that it is replaced by the destinationDirectory property rather than the classesDirectory property.
The compiler output directory can be changed using either of the following ways:
sourceSets {
main {
java {
destinationDirectory.set(file("${project.buildDir}/classes/${sourceSets.main.name}/java"))
}
}
}
OR
sourceSets {
main {
java {
destinationDirectory.value(project.getLayout().getBuildDirectory().dir("classes/${sourceSets.main.name}/java"));
}
}
}
In my opinion, the second option is better.
To read the output dir for a particular sourceSet use:
project.sourceSets.main.java.destinationDirectory.get()

Ignore generated resources from Spotless

My Project is using spotless plugin. I need to ignore java files from the generated-resources directory. How to do the same.
This is how I am using the plugin.
apply plugin: "com.diffplug.gradle.spotless"
spotless {
lineEndings = 'unix';
java {
eclipseFormatFile "eclipse-java-google-style.xml"
}
}
sourceSets has generated-resources directory included which I do not want to remove.
You can specify a target for the spotless formatter which allows includes and excludes.
I use the following in the top-level build.gradle in a multi-project build where all Java code resides in subdirectories under the modules directory:
subprojects {
...
spotless {
java {
target project.fileTree(project.rootDir) {
include '**/*.java'
exclude 'modules/*/generated/**/*.*'
}
googleJavaFormat()
}
}
...
}

How to include all src/test/resources/** AND src/main/java/**/*.html in the test sourceset in gradle?

I have the following and thought it was 'adding' to my sourceSet but actually just modified it..
sourceSets {
test {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.html"]
}
}
}
What I really want is both src/test/resources/** and the above as well. I don't want to exclude any files from src/test/resources though and the above is only including html from any directories I put there.
thanks,
Dean
The following will illustrate the technique using main (so it can be verified):
apply plugin: 'java'
sourceSets {
myExtra {
resources {
srcDirs "src/main/java"
includes = ["**/*.html"]
}
}
main {
resources {
source myExtra.resources
}
}
}
Proof of concept via the command-line:
bash$ ls src/main/java
abc.html
xyz.txt
bash$ ls src/main/resources/
def.html
ijk.txt
bash$ gradle clean jar
bash$ jar tf build/libs/myexample.jar
META-INF/
META-INF/MANIFEST.MF
abc.html
def.html
ijk.txt
In your case, change main to test. This answer was discovered via the Gradle doc for SourceDirectorySet. Interestingly, for 3.0, it contains a TODO:
TODO - configure includes/excludes for individual source dirs
which implies that this work-around (via this method) is probably necessary.
I got your point. I tried this and it worked . Please take a look into it:
sourceSets {
test {
resources {
srcDirs = ["src/main/java"]
includes = ["**/*.html"]
}
}
}
sourceSets.test.resources.srcDir 'src/test/resources'
Add these in build.gradle.
I was thinking whether or not to post this answer. So that if you are not satisfied with the previous answer, try the following hacky way (probably it will work with eclipse command):
apply plugin: 'java'
ConfigurableFileTree.metaClass.getAsSource = {
def fileTrees = delegate.asFileTrees
fileTrees.metaClass.getSrcDirTrees = {
return delegate as Set
}
fileTrees as SourceDirectorySet
}
sourceSets {
main {
resources {
srcDirs = [] // cleanup first
source fileTree('src/main/java').include('**/*.html').asSource
source fileTree('src/main/resources').asSource
}
}
}
Using srcDir may be what you want. Here's an example:
sourceSets {
main {
resources {
srcDir "src/main/resources"
exclude "file-to-be-excluded"
include "file-to-be-included"
srcDir "src/main/java"
include "**/*.html"
srcDir "image-folder-in-root"
include "**/*.png"
include "**/*.jpg"
exclude "**/*.xcf"
}
}
}
Not exactly what you asked for, but it could be helpful for someone who finds this question:
I only wanted to have the test resources next to the sources. So I only need to exclude the sources.
In your case, perhaps you could exclude those which you would mind getting in the JAR and/or classpath.
None of the other answers worked for me, and this did work:
sourceSets {
test {
resources {
srcDirs += "src/test/kotlin"
excludes = ["**/*.kt"]
}
}
}
Gradle 6.3.

How do I add resources to sourceSet with gradle?

Currently I have the following build.gradle file:
apply plugin: 'java'
repositories {
mavenCentral()
}
sourceSets {
main {
java {
srcDir 'src/model'
}
resources {
srcDir 'images/model'
}
}
test {
java {
srcDir 'tests/model'
}
resources {
srcDir 'images/model' // <=== NOT WORKING
}
}
}
dependencies {
compile files('libs/mnist-tools.jar', 'libs/gson-2.2.4.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
testCompile group: 'junit', name: 'junit', version: '4.+'
}
My repository if here: https://github.com/quinnliu/WalnutiQ
and 4 out of my 49 tests are failing because the tests in folder "tests/model" need a file within the folder "images/model". How do I add the resources correctly? Thanks!
I had a closer look at your build.gradle and it seems that paths are a little bit off.
You specify source as src/model, yet your project structure and Java source suggest that model is your package name, which means the source declaration should be:
main {
java {
srcDir 'src'
}
}
Same for tests:
test {
java {
srcDir 'tests'
}
}
Now, with missing resources. In your code you are using ImageIO.read(getClass().getResource(BMPFileName))
getClass().getResource() is using relative path to the resource. To keep the resources on the same level, you should update declaration for the resources and remove model:
test {
java {
srcDir 'tests'
}
resources {
srcDir 'images'
}
}
You might also need to run
./gradlew clean
before it works.
Here's the result with the updated build.gradle:
Hope it helps :)
The syntax used in your build script is correct. It's not clear to me why you add the same resource directory to both source sets, and why you claim that it isn't working in one case.
srcDir "foo" adds another directory. If you instead want to replace the default directory, use srcDirs = [ "foo" ] instead. However, this won't solve the problem at hand.
It would be good to see the code that loads the resources, to rule out any problems with that.

Resources