How to specify classes output directory for Gradle 4? - gradle

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()

Related

Can Gradle produce multiple Kotlin Native binaries (for one OS)?

Can I convince Gradle to produce multiple binaries? I have several Kotlin packages with files that have a proper "fun main(...)" but the default IntelliJ build.gradle file only allows me to specifiy one "compilations.main.entryPoint".
I could put the main functions into Kotlin classes or objects if that would help.
Changing the entryPoint argument to an array did not work :)
If it's not currently possible, is it a general limitation of Gradle or only of the "kotlin-multiplatform" plugin?
plugins {
id 'kotlin-multiplatform' version '1.3.11'
}
repositories {
mavenCentral()
}
kotlin {
targets {
// For ARM, preset should be changed to presets.iosArm32 or presets.iosArm64
// For Linux, preset should be changed to e.g. presets.linuxX64
// For MacOS, preset should be changed to e.g. presets.macosX64
fromPreset(presets.mingwX64, 'mingw')
configure([mingw]) {
// Comment to generate Kotlin/Native library (KLIB) instead of executable file:
compilations.main.outputKinds('executable')
// Change to specify fully qualified name of your application's entry point:
compilations.main.entryPoint = 'hello.main'
}
}
sourceSets {
// Note: To enable common source sets please comment out 'kotlin.import.noCommonSourceSets' property
// in gradle.properties file and re-import your project in IDE.
mingwMain {
}
mingwTest {
}
}
}
task runProgram {
def buildType = 'debug' // 'release' - Change to 'debug' to run application with debug symbols.
dependsOn "link${buildType.capitalize()}ExecutableMingw"
doLast {
def programFile = kotlin.targets.mingw.compilations.main.getBinary('EXECUTABLE', buildType)
exec {
executable programFile
args ''
}
}
}
In https://github.com/JetBrains/kotlin-native/issues/2505 I've just got the answer that this will be possible with Kotlin Native 1.3.20!

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 replace the default source folders for 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.

avro gradle plugin sample usage

I am trying to use the avro-gradle-plugin on github, but have not gotten any luck getting it to work. Does anyone have any sample code on how they get it to work?
I figured out how to do it myself. The following is a snippet that I would like to share for people who might run into the same issues as I did:
apply plugin: 'java'
apply plugin: 'avro-gradle-plugin'
sourceCompatibility = "1.6"
targetCompatibility = "1.6"
buildscript {
repositories {
maven {
// your maven repo information here
}
}
dependencies {
classpath 'org.apache.maven:maven-artifact:2.2.1'
classpath 'org.apache.avro:avro-compiler:1.7.1'
classpath 'org.apache.avro.gradle:avro-gradle-plugin:1.7.1'
}
}
compileAvro.source = 'src/main/avro'
compileAvro.destinationDir = file("$buildDir/generated-sources/avro")
sourceSets {
main {
java {
srcDir compileAvro.destinationDir
}
}
}
dependencies {
compileAvro
}
I found "com.commercehub.gradle.plugin.avro" gradle plugin to work better.
use the folllowing:
// Gradle 2.1 and later
plugins {
id "com.commercehub.gradle.plugin.avro" version "VERSION"
}
// Earlier versions of Gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.commercehub.gradle.plugin:gradle-avro-plugin:VERSION"
}
}
apply plugin: "com.commercehub.gradle.plugin.avro"
more details at https://github.com/commercehub-oss/gradle-avro-plugin
When evaluating a plugin the following questions needs to be asked:
Are generated files included into source jar?
Is plugin fast? Good plugin use avro tools api instead of forking VM for every file. For large amount of files creating VM for every file can take 10min to compile.
Do you need intermediate avsc files?
Is build incremental (i.e. do not regenerate all files unless one of the sources changed)?
Is plugin flexible enough to give access to generated schema files, so further actions, such as registration schema in schema repository can be made?
It is easy enough to implement without any plugin if you are not happy with plugin or need more flexibility.
//
// define source and destination
//
def avdlFiles = fileTree('src/Schemas').include('**/*.avdl')
// Do NOT generate into $buildDir, because IntelliJ will ignore files in
// this location and will show errors in source code
def generatedJavaDir = "generated/avro/java"
sourceSets.main.java.srcDir generatedJavaDir
//
// Make avro-tools available to the build script
//
buildscript {
dependencies {
classpath group:'org.apache.avro', name:'avro-tools' ,version: avro_version
}
}
//
// Define task's input and output, compile idl to schema and schema to java
//
task buildAvroDtos(){
group = "build"
inputs.files avdlFiles
outputs.dir generatedJavaDir
doLast{
avdlFiles.each { avdlFile ->
def parser = new org.apache.avro.compiler.idl.Idl(avdlFile)
parser.CompilationUnit().getTypes().each { schema ->
def compiler = new org.apache.avro.compiler.specific.SpecificCompiler(schema)
compiler.compileToDestination(avdlFile, new File(generatedJavaDir))
}
}
}
}
//
// Publish source jar, including generated files
//
task sourceJar(type: Jar, dependsOn: buildAvroDtos) {
from sourceSets.main.allSource
// Package schemas into source jar
into("Schemas") { from avdlFiles }
}
// Clean "generated" folder upon "clean" task
clean {
delete('generated')
}
Configuration for avro with gradle as build tool need to add along with applying java plugin.
below changes in settings.gradle
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
}
}
below changes in build.gradle
plugins {
id "com.github.davidmc24.gradle.plugin.avro" version "1.3.0"
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.apache.avro:avro:1.11.0"
}
generateAvroJava {
source("${projectDir}/src/main/resources/avro")//sourcepath avrofile
}
if you want to generate setter methods too add this task too in build.gradle
avro {
createSetters = true
}
link for reference

Resources