Better way to organize gradle pluginManagement block - java

Below is a example where, in order to add a custom-plugin to the application, we need to specify it dependency in resolution strategy and by using useModule, to add it in classpath
-------build.gradle----------
plugins {
id 'custom-plugin'
}
-------settings.gradle----------
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.namespace == 'custom-plugin') {
useModule('org.gradle.sample:custom-plugins:1.0.0')
}
}
}
repositories {
maven { url 'maven-repo' }
}
}
Is there any simpler/better way to add the dependency (useModule section)?
I don't want to add if condition and check the namespace requested.id.namespace every time for any new custom plugin I add.
Is there a way to avoid this just like in the old way of adding plugin in the application, wherein buildscript block we just have to add that dependency using classpath.
buildscript {
repositories {
maven { url "https://privaterepo.myemployer.com" }
}
dependencies {
classpath "org.gradle.sample:custom-plugins:1.0.0"
}

This depends, if the repository knows the requested requested.id.id, with the default .gradle.plugin suffix added. Your question led to another answer - and the example which I provide there, probably shows when it's required to use resolutionStrategy and when not.

Related

How execute annotation processing in gradle separatly from build task

I want to run QueryDsl Q-type generation in a separate task. I want that Q-type classes not to be created in a regular compileJava task, but the compiler sees the AnnotationProcessor in the classpath and creates them itself. I tried nulling the annotationProcessorPath, but then I couldn't restore its configuration in a separate task.
May be is it possible to exclude somehow dependencies of subtasks from the classpath?
compileJava {
options.annotationProcessorPath = null
}
tasks.register('generateQTypes'){
group 'build'
description 'Generate Q-Type classes with QueryDsl library'
dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
compileJava {
options.annotationProcessorPath = classpath
}
}
What is the best way to solve this problem?Thanks in advance!
I made the following solution
class QTypeGenerator extends DefaultTask {
#TaskAction
addDependencies() {
project.dependencies {
annotationProcessor(
'com.querydsl:querydsl-apt:4.1.4:jpa',
'javax.persistence:javax.persistence-api:2.2',
'javax.annotation:javax.annotation-api:1.3.1')
}
}
}
tasks.register("generateQTypeClasses", QTypeGenerator) {
group('build')
description('Generate Q-type classes by queryDsl in build directory with default path')
finalizedBy('compileJava')
doLast {
println("Q-types classes will gererated and stored in ${compileJava.options.annotationProcessorGeneratedSourcesDirectory}")
}
}

Generate Maven "provided" dependency in pom.xml from Gradle "compileOnly"

If I understand correctly, Gradle's compileOnly dependency corresponds to Gradle's older provided, and at the same time, Maven POM's provided. It works perfectly in the Gradle world.
But, compileOnly does not generate any provided dependency in pom.xml generated by maven-publish.
We are publishing a Maven artifact to Maven Central, using Gradle. We would like to declare provided explicitly in the published pom.xml from Gradle's compileOnly.
Does anyone know if there is any simple way to do that? Or, do we need to write our own Gradle scripting in :
publishing {
publications {
maven(MavenPublication) {
pom {
/* Our own Gradle scripting to declare provided dependencies. */
}
}
}
}
I know we can tweak it by scripting dirty like below, but we basically don't want to "script" in build.gradle as far as possible.
publishing {
publications {
maven(MavenPublication) {
pom {
withXml {
project.configurations.compileOnly.allDependencies.each { dependency ->
asNode().dependencies[0].appendNode("dependency").with {
it.appendNode("groupId", dependency.group)
it.appendNode("artifactId", dependency.name)
it.appendNode("version", dependency.version)
it.appendNode("scope", "provided")
}
}
}
}
}
}
}
I think scripting is the way to go... you can create a method och pass the pom e.g
publishing {
publications {
mavenDependencyList(MavenPublication) {
fixDependencyScope(pom)
}
}
}
void fixDependencyScope(pom) {
pom.withXml {
asNode().dependencies.'*'.findAll() {
it.scope.text() == 'compileOnly' && project.configurations.compile.allDependencies.find { dep ->
dep.name == it.artifactId.text()
}
}.each() {
it.scope*.value = 'provided'
}
}
}

How to find tasks of a certain type through all projects?

I have a multi-build Java project being built with Gradle.
To hide Illegal reflective access warnings I want to find JavaExec and Test tasks within several projects and provide the required JVM arguments. Rather than add these to each project, I want to apply this to all projects in the root build.gradle.
How do I find certain tasks of a certain type throughout all projects?
My intial attempt uses withType however I want to remove the duplication of repeating this for the JavaExec and Test task types. See below:
Attempt #1
allprojects {
repositories {
jcenter()
}
afterEvaluate {
project.tasks.withType(JavaExec) {
it.jvmArgs "--add-opens=java.base/java.lang=ALL-UNNAMED"
}
project.tasks.withType(Test) {
it.jvmArgs "--add-opens=java.base/java.lang=ALL-UNNAMED"
}
}
}
subprojects {
version = "0.0.1-SNAPSHOT"
}
Try this :
afterEvaluate {
[JavaExec, Test].each {
project.tasks.withType(it) {
it.jvmArgs "--add-opens=java.base/java.lang=ALL-UNNAMED"
}
}
}

How to call a task separately in gradle

My build.gradle file looks like below.
apply plugin: 'java'
repositories {
maven {
mavenCentral()
}
dependencies {
compile "commons-logging:commons-logging:1.0.4",
"commons-codec:commons-codec:1.3"
}
jar {
manifest{
attributes ("Product-Name" : project.name, "${manifestSectionName}")
attributes ("Product-Display-Name" : project.description, "${manifestSectionName}")
}
}
task build1 {
sourceSets {
main {
java {
srcDirs = ['src/java/com/abc/xyz/dir1']
}
}
}
buildDir = 'op'
jar{
archiveName = 'build1.jar'
}
}
task build2 {
sourceSets {
main {
java {
srcDirs = ['src/java/com/abc/xyz/dir2']
}
}
}
buildDir = 'op'
jar{
archiveName = 'build2.jar'
}
}
So now I want to call individual task to build individual jar, the way we invoke individual targets in Ant.
So when I am calling it like : gw clean build build2
its building build2.jar in correct way, but when I am running it like: gw clean build build1, its still building build2.jar only.
I am very new to gradle, so not sure about this.
Its still building build2.jar only, I am not sure why its happening .. can someone help me here?
Note that both tasks are independent of each other.
When configuring build1 and build2, you're configuring the unique, shared, main sourceSet and the unique, shared, jar task. Since build2 is configured after build1, it overrides the configuration set by build1.
What you want instead is two additional tasks in the build, which both create a jar with a different content:
task build1(type: Jar) {
dependsOn classes
archiveName = 'build1.jar'
from(sourceSets.main.output) {
include '**/package1/**/*'
}
}
task build2(type: Jar) {
dependsOn classes
archiveName = 'build2.jar'
from(sourceSets.main.output) {
include '**/package2/**/*'
}
}
But that looks to me like bad design. If you want to generate different jars, then you should probably have several subprojects, all using the java plugin and not needing any configuration.

Gradle - dependencies order of addition

I have one real issue with defining order of dependencies, eg. I have a gradle dependency which looks like this:
configurations {
defaults
configs
}
task extractDefaults(type: Copy) {
from { configurations.defaults.collect { it.isDirectory() ? it : zipTree(it) } }
into "$buildDir/defaults/"
}
in other file i have
dependencies {
compile project(':SOME_PROJECT')
defaults "OTHER_PROJECT_1:${VER}#zip"
defaults project(':OTHER_PROJECT_2').files('WEB')
}
in no matter in which order i will add defaults dependencies all files are overritten by "OTHER_PROJECT:${VER}#zip". I have multi project build. My question is how can i define defauts to be somehow ordered list (the order is specified by order of addition)?

Categories