Make gradle compileJava dependsOn spotlessApply - java

I have a Gradle project with several submodules. In my project there is a spotless task configured. Now I want to make a compileJava task dependent on spotlessApply task. I try it in this way:
subprojects {
apply plugin: 'java'
apply plugin: 'com.diffplug.gradle.spotless'
spotless {
java {
target 'src/**/*.java'
licenseHeaderFile "$rootDir/buildSrc/CopyrightHeader.java"
importOrder(['java', 'javax', 'org', 'com'])
eclipseFormatFile "$rootDir/buildSrc/formatter.xml"
}
format 'misc', {
target 'src/**/*.md', 'src/**/*.xml', 'src/**/*.xsd', 'src/**/*.xsl'
indentWithSpaces()
trimTrailingWhitespace()
endWithNewline()
}
}
compileJava.dependsOn spotlessApply
}
But it produces an error:
Could not get unknown property 'spotlessApply' for project (...) of
type org.gradle.api.Project.
I also tried something like this:
compileJava.dependsOn project.tasks.findByName('spotlessApply')
But it doesn't work.

The Spotless plugin creates its tasks in an project.afterEvaluate block to allow you to configure the extension before it creates the task(s) - see here
To solve this, simply depend on the task's name (i.e. as a string) instead and Gradle will resolve the task when its needed.
compileJava.dependsOn 'spotlessApply'

Related

How to list only the runtimeClasspath resolved dependencies in Gradle during a build?

I am trying to create a task in my build that will list all the runtimeClasspath dependencies before it builds the project. So basically, it should be the equivalent of the following command but for all the subprojects:
gradle dependencies --configuration runtimeClasspath
So far I have managed to come up with a task that lists all the dependencies:
subprojects {
task listDependencies(type: DependencyReportTask) {}
complileJava.dependsOn listDependencies
}
It works great in the sense that it lists all the dependencies of all the subprojects, but as mentioned above, it also lists a lot of stuff I don't need to see.
How do I limit the output of the above task to just runtimeClasspath?
Thanks!
Since you are defining a task of type DependencyReportTask, you can configure its configuration property, which will be the equivalent of the --configuration flag on the CLI.
So something like:
subprojects {
def listDeps = tasks.register("listDependencies", DependencyReportTask) {
setConfiguration("runtimeClasspath")
}
tasks.withType(JavaCompile).configureEach {
dependsOn(listDeps)
}
}
Note however that printing the runtimeClasspath before executing compileJava is a bit weird. The classpath used by the compile task will be compileClasspath.
Edited to use lazy task API as there is otherwise an ordering problem with plugin application
A Kotlin version of the above accepted answer:
val listDeps = tasks.register<DependencyReportTask>("listDependencies") {
setConfiguration("compileClasspath")
}
tasks.withType<JavaCompile> {
dependsOn(listDeps)
}

Gradle building Spring Boot library without Main Class

I am trying to build a Spring Boot/Gradle project and create a jar without a main class. My purpose is that this project is a library that will be pulled in by other projects therefore the library project does not require a main class to run. Unfortunately, no matter what kind of gradle config I write I keep getting errors when I try to build install about not having a main class or not being able to find the bootJar task.
Here's what my gradle file looks like:
plugins {
id 'org.springframework.boot' version '2.1.7.RELEASE' apply false
}
apply plugin: 'io.spring.dependency-management'
apply plugin: 'maven'
dependencyManagement {
imports {
mavenBom org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES
}
}
repositories {
mavenCentral()
}
jar {
enabled = true
}
bootJar.dependsOn fooTask
But when I run this I get the following error:
Could not get unknown property 'bootJar' for root project
'foo-library' of type org.gradle.api.Project.
What in my configuration needs to change?
Disable bootJar in your build.gradle
bootJar {
enabled = false
}

How to run shadow jar with a gradle task?

I want to run my app after building it with the shadow jar plugin.
build.gradle:
plugins {
id 'java'
id "org.jetbrains.kotlin.jvm" version "1.3.21"
id "com.github.johnrengelman.shadow" version "5.0.0"
}
group 'org.example.java'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
repositories {
jcenter()
}
dependencies {
compile "io.ktor:ktor-server-netty:1.1.3"
}
I also have a global init.gradle:
gradle.projectsLoaded {
rootProject.allprojects {
buildDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
}
So now the fat jar can be built to my global build directory with the shadowJar task. But I want to be able to run and build it with just one run configuration in IntelliJ. How do I do that?
Maybe there is another way to let gradle redirect all my output to a global build directory. I don't want to configure each IntelliJ project with the same output path manually. Suggestions are welcome.
Thank you :)
You should not touch the buildDir property for achieving what you want.
Instead, you should create a JavaExec task that will start the application from the shadow jar.
If you want that execution to be at a different place than the default location of the generated jar, you should either change the output of the shadow task itself, and only that output or make your execution task depend on a copy task that would move the shadow jar around.
Something like:
shadowJar {
destinationDir = "/Users/User/Builds/${rootProject.name}/${project.name}"
}
task runApp(type: JavaExec) {
main = "your.main.Class
classpath = shadowJar.archiveFile // use archivePath before Gradle 5.1
}

Gradle - Create jar only if tests pass

I am new to Gradle. I would like to manipulate the following build.gradle contents to do this. Instead of separately running the tests then building the jar via separate commands, I'd like to do both in one command, except that the jar does not get created if one of the tests fail (it will not even try to build the jar).
apply plugin: 'java'
apply plugin: 'eclipse'
version = '1.0'
sourceCompatibility = 1.6
targetCompatibility = 1.6
// Create a single Jar with all dependencies
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Jar File Example',
'Implementation-Version': version,
'Main-Class': 'com.axa.openam'
}
baseName = project.name
from {
configurations.compile.collect {
it.isDirectory() ? it : zipTree(it)
}
}
}
// Get dependencies from Maven central repository
repositories {
mavenCentral()
}
test {
testLogging {
showStandardStreams = true
}
}
// Project dependencies
dependencies {
compile 'com.google.code.gson:gson:2.5'
testCompile 'junit:junit:4.12'
}
Thanks!
The simplest solution is to place all the tasks you want gradle to execute in order. So you may use the following:
gradle clean test jar
Tasks Breakout
clean: this is used mainly just to safely remove the last outdated jar (this is not mandatory);
test: execute the tests;
jar: create the jar artifact.
Key point: if one of the task fails for some reason gradle stops its execution.
So if just a single test fails for some reason an exception is thrown and the jar file is not created at all.
Alternative solution: add 'test' as dependency of 'jar'
Just to explore some other possibilities: modify the build.gralde file as follows:
[...]
jar {
dependsOn 'test'
[...]
}
[...]
Now every time you run gradle jar the test task is automatically executed before.
Emulate the pure command line solution using 'dependsOn'
To emulate the first command line approach (i.e., gradle clean test jar) using the dependency method you have to further modify the build.gradle. This is because is not assured that multiple dependsOn statements are evaluated in order:
[...]
jar {
dependsOn 'clean'
dependsOn 'test'
tasks.findByName('test').mustRunAfter 'clean'
[...]
}
[...]
Now you can use:
gradle jar
and both the tasks clean and test are executed (in the right order) before the actual jar task.

Gradle error with lack of mainClassName property in gradle build

I have graddle configuration with two subprojects and when I want do build the project the following error is thrown:
Executing external task 'build'...
:core:compileJava
:core:processResources UP-TO-DATE
:core:classes
:core:jar
:core:startScripts FAILED
FAILURE: Build failed with an exception.
* What went wrong:
A problem was found with the configuration of task ':core:startScripts'.
> No value has been specified for property 'mainClassName'.
My configuration:
ROOT - build.gradle:
subprojects {
apply plugin: 'java'
apply plugin: 'application'
group = 'pl.morecraft.dev.morepianer'
repositories {
mavenLocal()
mavenCentral()
}
run {
main = project.getProperty('mainClassName')
}
jar {
manifest {
attributes 'Implementation-Title': project.getProperty('name'),
'Implementation-Version': project.getProperty('version'),
'Main-Class': project.getProperty('mainClassName')
}
}
}
task copyJars(type: Copy, dependsOn: subprojects.jar) {
from(subprojects.jar)
into project.file('/jars')
}
ROOT - setting.gradle:
include 'app'
include 'core'
APP PROJECT - build.gradle:
EMPTY
CORE PROJECT - build.gradle:
dependencies {
compile 'com.google.dagger:dagger:2.4'
compile 'com.google.dagger:dagger-compiler:2.4'
}
AND BOTH SUBPROJECTS (SIMILAR) - gradle.properties:
version = 0.1-SNAPSHOT
name = MorePianer Core Lib
mainClassName = pl.morecraft.dev.morepianer.core.Core
I've tried to add the mainClassName property in many places, but it does not work. This is even stranger, that It worked a couple days ago as it is. I'm using gradle for first time and I'm thinking about switching back to maven.
The application plugin needs to know the main class for when it bundles the application.
In your case, you apply the application plugin for each subproject without specifying the main class for each of those subprojects.
I had the same problem and fixed it by specifying "mainClassName" at the same level as apply plugin: 'application' :
apply plugin: 'application'
mainClassName = 'com.something.MyMainClass'
If you want to specify it in the gradle.properties file you might have to write it as : projectName.mainClassName = ..
Instead of setting up mainClassName try to create
task run(type: JavaExec, dependsOn: classes) {
main = 'com.something.MyMainClass'
classpath = sourceSets.main.runtimeClasspath
}
Please look at Gradle fails when executes run task for scala
Whenever we bind a gradle script with the application plugin, Gradle expects us to point out the starting point of the application. This is neccessary because, Gradle will start bundling your application (jar/zip) using the given location as the entry point.
This error is thrown simply because Gradle knows that you want to bundle your application but is clueless about where to start the bundling process.
One can specify the mainClassName as a project extended property:
ext {
mainClassName = 'com.something.MyMainClass'
}
I faced the same issue in my project and solved it by excluding from gradle.properties:
#ogr.gradle.configurationdemand = true

Categories

Resources