What is the role of versionMapping in maven-publish plugin - java

What option would be preferable, if we have to generate a java library using maven-publish plugin
Option 1:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
}
}
}
Option 2:
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
versionMapping {
allVariants {
fromResolutionResult()
}
}
}
}
}

What is the role of versionMapping in maven-publish plugin
Per the docs:
Two strategies are supported for publishing dependencies:
-- snip
This is done by using the versionMapping DSL method
What option would be preferable
That is entirely dependent on your use case/needs. As mentioned in the docs, there are two strategies for dependencies: declared versions and resolved versions. Which one you use is entirely dependent on your use case or needs.

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}")
}
}

How to publish a shadow jar with an empty pom using gradle maven-publish plugin and Kotlin DSL?

The shadow plugin documentation has an example for groovy but I do not understand how to translate this to Kotlin.
Groovy example from https://imperceptiblethoughts.com/shadow/publishing :
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
}
}
}
My best attempt at the Kotlin version:
publishing {
publications {
create<MavenPublication>("pluginMaven") {
artifact(tasks["shadowJar"])
project.shadow.component(this)
}
}
}
With the above Kotlin version, shadowed dependencies show up in the resulting pom as runtime dependencies, which defies of purpose of shadowing.
The solution is
tasks {
shadowJar {
archiveClassifier.set("")
minimize()
}
}
Some background in this github issue.

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'
}
}
}

Better way to organize gradle pluginManagement block

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.

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"
}
}
}

Categories