How to specify archive classifier for shadowJar plugin in gradle 5+ - gradle

Starting from version 5 gradle changed Archive Tasks behavior
This breaks shadowJar task default behavior which doesn't create <name>-<version>-all.jar artifact any more.
How to revert this behavior and create *-all.jar?

Instead of using deprecated classifier and archiveName configure shadowJar plugin the following way:
shadowJar {
archiveClassifier = 'all'
}
Or since Gradle 5.1 using Property:
shadowJar {
archiveClassifier.set('all')
}
See more about the issue discussion:
https://github.com/johnrengelman/shadow/issues/446#issuecomment-460328699
https://github.com/johnrengelman/shadow/issues/450

Related

Gradle 'war' plugin how to change name of an archive

How can I change the name of war?
I already tried (I found these params in documentation https://docs.gradle.org/4.10.2/dsl/org.gradle.api.tasks.bundling.War.html)
war {
baseName = 'service'
archiveName 'service.war'
}
However, this is not working. I am still getting a name with a snapshot version.
./build/libs/search-0.0.1-SNAPSHOT.war
I am using Gradle 4.10 and Spring Boot 2.1.2.RELEASE.
Please refer to this documentation : Spring Boot Gradle reference
To sum up: when applying the Spring Boot gradle plugin together with war plugin, the war task is disabled by default and "replaced" by the SpringBoot bootWar task.
So if you want to configure the war artefact, you will need to configure the bootWar task instead of base war task :
bootWar {
baseName = 'service'
archiveName 'service.war'
}
Additional notes:
in Gradle 5.x , archiveName has been deprecated, and you should use archiveFileName instead
if you set the archiveName property you don't need to set baseName property
M. Ricciuti answer is correct, with the caveat that even though archiveName has been deprecated in Gradle 5.x, Spring Boot is still using it in 2.1.6.RELEASE. For example, if the bootWar task was configured with the new archiveFileName property like this:
bootWar {
archiveFileName 'service.war'
}
you will get this error:
Could not find method archiveFileName() for arguments [service.war] on task ':bootWar' of type org.springframework.boot.gradle.tasks.bundling.BootWar.
Use archiveName for now. See Spring BootWar class Java doc for details. They may add archiveFileName in the future.
bootWar {
archiveFileName.set 'service.war'
}
codemule - answer is correct, with a different error message when archiveFileName was used in bootWar task. I am using Gradle 6.5.1.
With the below bootWar task
bootWar {
archiveFileName 'bst.war'
}
I got the error message
A problem occurred evaluating root project 'example'.
> No signature of method: build_1z1dezuc71i4g9wsz51um0q6o.bootWar() is applicable for argument types: (build_1z1dezuc71i4g9wsz51um0q6o$_run_closure1) values: [build_1z1dezuc71i4g9wsz51um0q6o$_run_closure1#7abe6e]
It disappeared when bootWar task was configured with archiveName
bootWar {
archiveName 'example.war'
}

Gradle, shadowJar: use relocate inside task

I have the following task:
task myJar(type: Jar) {
archiveName = 'myJar.jar'
includeEmptyDirs = false
destinationDir = rootProject.libsDir
dependsOn compileJava
manifest.attributes('Class-Path': '../lib/commons-lang-2.5.jar')
into '/', {
from compileJava.destinationDir
include 'com/myCompany/project/util/order/**',
'com/myCompany/project/event/**',
}
}
and I would like to relocate all classes from com/myCompany/project/event/** to com/myCompany/relocated/project/event/** (so that some apps using my jar and having com.myCompany.project.event package defined will avoid any possible conflicts)
I discovered that it can be done using shadow plugin and I tried to add
relocate 'com.myCompany.project.event.', 'com.myCompany.relocated.project.event.'
under this task but it doesn't seem to work.
Does anybody know where I should add this line?
You can achieve this by adding below plugin to your build.gradle
apply plugin: 'com.github.johnrengelman.shadow'
After adding this plugin add below code to your build.gradle file
shadowJar {
relocate 'com.myCompany.project.event', 'com.myCompany.relocated.project.event'
}
After adding this, to ensure your ShadowJar task runs before build, add this line at the end
assemble.dependsOn shadowJar
This will ensure that shadow jar task is triggered before assemble/build task during gradle build.
On doing the Gradle build, you should see all your packages and their corresponding dependencies relocated from 'com.myCompany.project.event' to 'com.myCompany.relocated.project.event'.
For more info you can refer to ShadowJarUserGuide

How can I have Teamcity Artifactory plugin invoke bootJar instead of Jar in Gradle?

We are using Gradle 4.8.1 to generate Spring Boot executable jars. This works fine locally. However, we are using Teamcity to publish our artifacts into Artifactory.
The issue is, to my understanding, that the "artifactoryPublish" task invokes the "jar" task in Gradle, which uploads artifacts from "Archives". So, irrespective of whether teamcity invokes the "assemble" task, or the "bootjar" task, or the "build" task, the artifactory plugin is taking the output of the "jar" task in the end and publishes that, whereas we'd like to have the output of the "bootjar" task (fat jar) in artifactory.
Is there any way I can force artifactoryPublish to run bootjar instead of jar ? Or for the jar task to create a fat jar as well ? Or should I consider another approach ?
Here's my build.gradle from one of the subprojects
plugins {
id "org.springframework.boot" version "2.0.4.RELEASE"
id "io.spring.dependency-management" version "1.0.6.RELEASE"
}
apply plugin: 'java'
repositories {
mavenCentral()
}
description = 'atlas-data-service'
// Dynamically insert TeamCity build number if available
if (hasProperty("teamcity")) {
version = teamcity["build.number"]
println "Release version with TeamCity build number passed into gradle is " + version
} else {
// Take the default appVersion defined in top level build.gradle when building outside of TeamCity
version = "$appVersion"
}
jar {
baseName = 'data-service'
enabled = true
}
bootJar {
mainClassName = 'c.m.f.a.dataservice.AtlasDataServiceApplication'
baseName = 'data-service'
enabled = true
classifier = 'boot'
}
dependencies {
...
}
This question is from last year, but updating in case someone else comes looking with the same issue.
I used the Maven-publish plugin to get the job done.
https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/html/#publishing-your-application-maven-publish
apply plugin: 'maven-publish'
publishing.publications {
bootJava(MavenPublication) {
artifact bootJar
}
}

Sequencing dependencies of multiple Gradle plugin tasks

Please note: Although I specifically mention two Gradle plugins here, this is 100% a question about understanding task dependencies in Gradle, and does not require any knowledge of the individual plugins (I think)!
I have a project that will use two Gradle plugins:
The Gradle Shadow plugin, which will produce a self-contained "fat jar" (basically a large jar with all my classes plus the classes of all my transitive dependencies, which then allows me to just run java -jar myapp.jar without having to manage the jar's external classpath, etc.). This will produce a fat jar at build/libs/myapp.jar; and
The Gradle Launch4J plugin, which uses Launch4J under the hood to convert a jar into a native executable (EXE, etc.). Obviously the fat jar has to be created prior to the Launch4J tasks run, otherwise they'll have nothing to wrap inside of an EXE!
Here's my build.gradle:
import com.github.jengelman.gradle.plugins.shadow.transformers.ServiceFileTransformer
plugins {
id 'groovy'
id 'application'
id 'maven-publish'
id 'com.github.johnrengelman.shadow' version '1.2.3'
id 'edu.sc.seis.launch4j' version '2.3.0'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
group = 'hotmeatballsoup'
mainClassName = 'com.me.myapp.Driver'
repositories {
mavenCentral()
jcenter()
}
dependencies {
compile(
'org.codehaus.groovy:groovy-all:2.4.7'
,'org.slf4j:slf4j-api:1.7.24'
,'org.slf4j:slf4j-simple:1.7.24'
)
}
manifest {
attributes 'Main-Class': mainClassName
}
jar {
manifest {
attributes 'Main-Class': mainClassName
}
baseName = 'zimbus'
}
shadowJar {
transform(ServiceFileTransformer) {
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
exclude 'LICENSE*'
}
transform(com.github.jengelman.gradle.plugins.shadow.transformers.AppendingTransformer) {
resource = 'reference.conf'
}
classifier = ''
}
publishing {
publications {
shadow(MavenPublication) {
from components.shadow
artifactId = 'zimbus'
}
}
}
launch4j {
outfile = 'zimbus.exe'
mainClassName = 'com.me.myapp.Driver'
icon = 'zimbus.ico'
jar = 'build/libs/gradle-launch4j-example.jar'
}
At the command-line I run:
./gradlew clean build shadowJar createAllExecutables
The intention here is that I want the fat jar created first (invoked when shadowJar runs) and then for Launch4J to kick in (which is invoked when createAllExecutables runs). But when I run this I get the following exception:
:createExe FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':createExe'.
> Launch4J finished with non-zero exit value 1
launch4j: Application jar doesn't exist.
I'm pretty sure the createAllExecutables task is firing before the shadowJar task, and thus having nothing (no fat jar) to bundle up inside an EXE.
Can someone confirm my suspicion and help me define the dependsOn declaration that will order my tasks correctly? Or if the tasks are executing in the correct order, maybe offer any ideas as to what is causing the error?
Once you write
createAllExecutables.dependsOn shadowJar
you'll define the dependency between createAllExecutables task and shadowJar, which means every time Gradle decide to invoke createAllExecutables (e.g. because you pass that to the command line, or other task will depend on it) shadowJar will also be added to the task graph. So in that case when you invoke gradle createAllExecutables the shadowJar will be also executed.
But you can also write
createAllExecutables.mustRunAfter shadowJar
In that case, you won't introduce any dependency relation between tasks, but you will instrument Gradle about anticipated order for those two tasks. In that case, once you invoke gradle createAllExecutables the shadowJar won't be executed.
I think the dependsOn relation is more applicable in your case, since in order to create executables you need to have fat jar already, so it's a depend on relation, not must run after.

gradle build fails cannot find sonar plugin "sonar-runner"

My gradle project cannot build. It fails with Plugin with id 'sonar-runner' not found.
Here's my build.gradle
subprojects {
apply plugin: 'sonar-runner'
}
I've refreshed my Gradle project. Then I've deleted my ~/.gradle/caches folder, but didn't work. Then I deleted my entire ~/.gradle folder, still the same error.
Any ideas please?
It's funny that gradle build doesn't run and gives me that exception, but bash gradle build runs fine, can someone clarify the difference in between? Thanks. My setup is on Mac OSX 10.11.6.
From https://docs.sonarqube.org/display/SONARQUBE51/Analyzing+with+Gradle:
Users of Gradle Sonar or Sonar Runner Plugins ? The existing Gradle
Sonar Runner and Gradle Sonar plugins, which are part of the Gradle
distribution, should no longer be used (See this official note from
the Gradleware team). The use of the Gradle SonarQube plugin is
recommended instead.
You have to use it as described at https://plugins.gradle.org/plugin/org.sonarqube
Build script snippet for use in all Gradle versions:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.2.1"
}
}
apply plugin: "org.sonarqube"
Build script snippet for new, incubating, plugin mechanism introduced in Gradle 2.1:
plugins {
id "org.sonarqube" version "2.2.1"
}
Issue discussing this problem:
https://discuss.gradle.org/t/plugin-with-id-org-sonarqube-not-found/11588/10

Resources