How to check java version when running gradle? - gradle

One of my project requires Java 1.8, but sometimes we didn't notice we are using older java so that we will get some strange errors.
I want to add the checking in build.gradle, so that when we run any task, it will firstly check the version, and prints error and quit immediately.
I tried to add the checking directly in build.gradle on the first line, but it still do some others tasks e.g. (clean, compileJava) before the checking happens, when I run:
$ ./gradlew
How to do it correctly?

If you put the check very early in your build lifecycle (plain check in the beginning of your build.gradle file or in the apply method of a plugin) you shouldn't see any tasks executed.
you can use JavaVersion enum for that which is part of the gradle api:
if(JavaVersion.current() != JavaVersion.VERSION_1_8){
throw new GradleException("This build must be run with java 8")
}

The accepted answer is nice however it could be improved a little bit by making it more generic. Indeed instead of comparing the current version with an explicit version, we could rely on the value of targetCompatibility instead (assuming it has been set properly) as next:
if (JavaVersion.current() != project.targetCompatibility) {
throw new GradleException("The java version used ${JavaVersion.current()} is not the expected version ${project.targetCompatibility}.")
}

Related

Gradle Idea plugin - issues with specifing test sources

I'm trying to create a custom source set and mark its contents in Intellij Idea as a Test Sources Root. I tried to use idea plugin and do it according to the gradle official website but it is not clear for me how it works.
First of all the documentation specifies the following configuration setup
idea {
module {
testSources.from(sourceSets["intTest"].java.srcDirs)
}
}
When I try to use it i receive Unresolved reference: testSources. Where is it coming from?
Then I tried to use:
idea {
module {
testSourceDirs = intTest.java.srcDirs
}
}
it works fine as long as I use only Java. After applying Kotlin plugin however, both kotlin and java + resources folder are again treated as Sources Root not Test Sources. To fix that I had to change from:
testSourceDirs = intTest.java.srcDirs
to:
testSourceDirs = intTest.kotlin.srcDirs
and now all folders are Test Source Root again. Since kotlin.srcDirs also includes java.srcDirs it looks like you have to specify all, otherwise it is ignored...
Now the real issue came when I used gradle-avro-plugin. Applying it made my folders marked as Sources Root again. I believe it is because it adds another avro directory, but just to main source set.
Does anyone know how to make it marked as Test Sources having both kotlin and avro plugin applied? Am I doing something wrong here? Beacause this beheviour seems to be buggy in the first place.
Tested with:
IntelliJ IDEA 2022.3.1 (Ultimate Edition)
Gradle 6.8.3 and 7.4.2
Plugin id("com.github.davidmc24.gradle.plugin.avro") version "1.5.0"
Plugin kotlin("jvm") version "1.7.0"

WIthin nebula/gradle, how can I inject the version being released into the jar being published?

We have a tool that runs from the command line. One of the commands is -version.
Before we converted to the nebula release plugin, the version was in the gradle.properties file, and as part of the build we copied it from there to a src/main/resources/version.txt file, that was later read by the tool to output the version.
But now the version is never in a file that's checked into git. Instead, it is only known during the nebula release process.
We want to obtain that version during the nebula release process and inject it into the jar that nebula is about to publish. For example, it could be added to the manifest.
We've tried to figure out how to do this, but don't see any examples online, and nothing about it in the documentation.
Simply create a task that caches the version that is dynamically inferred by Nebula.
Since you originally copied/created src/main/resources/version.txt, we'll use that that model our task.
Assuming a simple/standard Java project, using the Kotlin DSL:
val cacheNebulaVersion by tasks.registering {
mustRunAfter(tasks.named("release"))
doLast {
val sourceSets = project.extensions.getByName("sourceSets") as SourceSetContainer
sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).output.resourcesDir?.let {
// If there are not existing resources in your project then you must create
// the resources dir otherwise a FileNotFoundException will be thrown.
if (!it.exists()) {
it.mkdirs()
}
File(it, "version.txt").printWriter().use { out ->
out.println(project.version)
}
}
}
}
When I invoke ./gradlew clean build snapshot cacheNebulaVersion, the version produced by Nebula is cached/created at src/main/resources/version.txt in the build output. The task above does not bundle it with the jar.
Hopefully that gives you an idea what to do.

Is it possible to pass a parameter to settings.gradle

I would like to add a command line parameter to completetly skip some subprojects for performance reasons. My settings.gradle looks like this:
rootProject.name='MyProject'
if (!rootProject.hasProperty('NO_LIBRARY_BUILD')) {
print "=== BUILDING OF LIBRARY PROJECTS. Pass -PNO_LIBRARY_BUILD to gradle to skip building ==="
include('Lib1')
project(':Lib1').projectDir=file('Path/to/Lib1')
include('Lib2')
project(':Lib2').projectDir=file('Path/to/Lib2')
}
else {
print "=== SKIPPING BUILD OF LIBRARY PROJECTS ==="
}
However, this does not work - passing -PNO_LIBRARY_BUILD still enters the "building" part of the if. I assume that these properties are not passed to rootProject, but somewhere else.
How can I access (more so, how can I check for the existence of) the NO_LIBRARY_BUILD command line parameter from the settings gradle?
I found that what worked was using simply
hasProperty('NO_BUILD_LIBRARIES') without specifying the project.
Tested on Gradle 7.1.1. Just using hasProperty does not work. Using settings.hasProperty('abc') works with -Pabc=true.
Reference: https://docs.gradle.org/current/dsl/org.gradle.api.initialization.Settings.html

How to pass system properties to the tests in gradle in the smart way?

build.gradle
tasks.withType(Test){
systemProperties=System.properties
println systemProperties['param']
}
Now I can either pass parameters in the command line:
gradle test -Dparam=10
or put them in gradle.properties:
systemProp.param=15
Ideally I would like to put the defaults in the gradle.properties, and be able to overwrite them from the command line. Unfortunately if I do that, the gradle.properties has precedence, and -Dparam=10 is ignored.
Could you offer any solutions on that?
https://issues.gradle.org/browse/GRADLE-2122
It works since 2.12 or 2.13 "the smart way" already!
The example above is working, the command line -D option overdrives the defaults in gradle.properties
I am using gradle 2.12 and sharing how I used it:
test {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
I have JUnit tests that I wanted to skip unless a property was used to include such tests. Using JUnit Assume for including the tests conditionally:
//first line of test
assumeThat(Boolean.parseBoolean(System.getProperty("deep.test.run","false"),true)
Doing this with gradle required that the system property provided at the time of running gradle build, shown here,
gradle build -Ddeep.test.run=true
was indeed passed through to the tests.
Hope this helps others trying out this approach for running tests conditionally.

Gradle Version Replacing characters

I am using nebula release plugin, which generates -SNAPSHOTS for snapshot builds, also using the nebula ospackage plugin to buildRpm, I am trying to use the same version as of project for RPM as well, but rpm complains about - as illegal character, Is there a way to get this fix keeping the same nomenclature, i know the rpm nomenclature standards doesn't allow this.
Can I do something like in build.gradle project.version.toString().replace("_",".")
If project.version is where the nebula-release plugin stores the generated version string, then you should be able to use:
project.version.replace('-','.')
(toString() is not necessary, but should work with it included too.)
I fixed with following work around:
if (project.version.toString().contains("-")){
version = project.version.toString().replaceAll("-", ".")
} else {
version = project.version
}

Resources