How to force artifact/module name with Gradle build - gradle

Please note: even though this question specifically mentions Bamboo CI and the Gradle ShadowJar plugin, I believe this is a basic Gradle config question at heart, and believe it can be answered by any battle-weary Gradle Guru.
I have a Groovy app that is built with Gradle, where build.gradle is:
apply plugin: 'groovy'
apply plugin: 'maven'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'eclipse'
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
group = 'com.me.myapp'
mainClassName = "com.me.myapp.MyAppDriver"
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
}
}
dependencies {
// Omitted for brevity
}
jar {
manifest {
attributes 'Main-Class': mainClassName
}
}
repositories {
mavenLocal()
mavenCentral()
}
shadowJar {
classifier = ''
mergeServiceFiles {
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
}
}
artifacts {
archives(file("${buildDir}/libs/myapp-${version}.jar")) {
name "myapp"
classifier ""
builtBy shadowJar
}
}
task wrapper(type: Wrapper) {
gradleVersion = '2.3'
}
And where gradle.properties is:
group=com.me.myapp
version=1.0.0
As you can see, I'm using ShadowJar to produce a self-contained "fat JAR" for my app. When I run gradle clean build shadowJar on my local machine, Gradle produces a build/libs/myapp-1.0.0.jar artifact/archive. However, when this same command is ran from our CI server (Bamboo), Gradle produces a build/libs/MYAPP-KEY-1.0.0.jar artifact/archive, where MYAPP-KEY is the Bamboo "build key" (essentially, a unique key/label identifying the build on the server). If you're clueless as to what I'm talking about, I don't think that really matters. What is important to understand is that Bamboo will check out the source code for myapp to a folder named MYAPP-KEY on the CI server. So locally myapp/ is the root of my project, but on CI MYAPP-KEY is the root of my project.
The main point is that I am not explicitly defining something in my Gradle config, and so it seems that Gradle is using the name of the project root to produce the name of the built JAR. What is this "something" and how/where do I define it? The desired end objective is to produce a build/libs/myapp-1.0.0.jar both locally and on CI.

please, look at https://docs.gradle.org/current/dsl/org.gradle.api.tasks.bundling.Jar.html
you can specify base name or full archive name of jar
add it to your jar section

Related

gradle does not fetch dependencies after upgrade from 5.1.1 to 6.4.1

I have several services that uses gradle 5.1.1 with java 8.
As we want to upgrade to Java 13, we first need to upgrade to gradle 6after doing so, some dependencies are not fetched.
Those dependencies are listed with compile() under a dependency which is our jar library and still built with gradle 5.1.1
our libraries are stored in a S3 bucket and we use shadowjar to generate the end jar.
so, for example:
I have project A which I want to upgrdae.
Project A has project B as a dependency (compile)
Project B has google guava as a dependency (also with compile)
Now, project A, that under gradle 5.1.1 had fetched guava with no problems, alerting me that it is missing guava after upgrading to gradle 6.
I use local computer installed gradle (not wrapper).
Here are the important build.gradle parts:
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
ext.ver = [
'springboot': '2.2.0.RELEASE',
'slf4j' : '1.7.12'
]
dependencies {
classpath "org.springframework.boot:spring-boot-gradle-plugin:${ver.springboot}"
classpath 'io.spring.gradle:dependency-management-plugin:1.0.7.BUILD-SNAPSHOT'
classpath 'com.github.jengelman.gradle.plugins:shadow:5.2.0'
classpath 'com.amazonaws:aws-java-sdk-core:1.11.5'
}
}
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'maven'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'maven-publish'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
compileJava {
sourceCompatibility = JavaVersion.VERSION_1_8
}
configurations {
compile.exclude module: 'spring-boot-starter-logging'
testCompile.exclude module: 'spring-boot-starter-logging'
runtime.exclude module: 'spring-boot-starter-logging'
compile.exclude group: 'ch.qos.logback'
}
configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 10, 'seconds'
resolutionStrategy.cacheChangingModulesFor 10, 'seconds'
}
dependencyManagement {
applyMavenExclusions = false
}
repositories {
mavenLocal()
maven {
url "s3://bucket"
credentials(AwsCredentials) {
accessKey = awsCredentials.AWSAccessKeyId
secretKey = awsCredentials.AWSSecretKey
}
metadataSources {
artifact()
}
}
mavenCentral()
}
dependencies {
compile("com.test:projectB:1.0.0")
...
}
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
shadowJar {
classifier = ''
baseName = 'project-A'
manifest {
attributes 'Main-Class': 'com.test.projectA.Starter'
}
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories']
mergeStrategy = "append"
}
}
Could this be because project B was not built with new gradle?
unfortunately, I cannot create a real reproducer as those libraries are real code of the company I work at.
Thanks and Regards,
Ido
The metadataSources declaration of the s3 bucket Maven repository is most likely the root cause why transitive dependencies of projectB are not resolved. The documentation is quite a bit vague here, but I suspect artifact() looks for the actual jar file only and not for the POM file, hence transitive dependency resolution is not performed. You should be able to see this behavior when running the build with switches --info and --refresh-dependencies.
Thankfully, this is quite easy to fix. Add mavenPom() and Gradle will try to resolve the POM first and with that, dependency resolution should be back to normal.
And while you're at it, you might want to read the upgrading from Gradle 5 guide and get rid of the compile configuration in favor of implementation. You should be able to see a warning similar to this when running the build with --warning-mode all:
The compile configuration has been deprecated for dependency declaration. This will fail with an error in Gradle 7.0. Please use the implementation or api configuration instead. Consult the upgrading guide for further information: https://docs.gradle.org/6.4.1/userguide/upgrading_version_5.html#dependencies_should_no_longer_be_declared_using_the_compile_and_runtime_configurations

unable to create a executable spring boot jar by the bootJar task

basically I need to create a spring boot jar to run system spring-server service on my server
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
ext {
spring_boot_version = '1.5.7.RELEASE'
spring_version = '4.3.11.RELEASE'
}
repositories {
mavenLocal()
jcenter()
mavenCentral()
maven { url 'https://dl.bintray.com/kotlin/exposed' }
maven { url 'https://jitpack.io' }
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
}
apply plugin: 'kotlin'
apply plugin: 'java'
apply plugin: 'net.corda.plugins.cordformation'
apply plugin: 'net.corda.plugins.quasar-utils'
bootJar {
basName = 'corda-webserver'
version = '1.0.0'
}
How can I achieve this is there something wrong with gradle dependencies or plugins?
I tried springboot task as well
So there's not enough information here to be sure of what the issue could be; so here are a few ideas.
Start by cleaning gradle cache. ./gradlew clean
Obviously the issue here is dependencies, you need to make sure gradle is able to build your project, and download dependencies.
./gradlew deployNodes (if you're using one of the corda sample projects) will build all of the files locally and should pull in the dependencies for you.
R3 now uses software.r3.com as the 'official' link to the artifact repository, you may want to take a look there and maybe look at whether the downloads are still good.
good luck!

dependent jar is not bundled along with project jar Gradle

I have a project corehibernate and a project coregeneral. corehibernate is dependent on coregeneral. I need the jar file of coregeneral to be bundled along with the corehibernate jar. I tried various versions of the build.gradle thing, nothing worked.
I tried compile files("../coregeneral/build/libs/coregeneral.jar")
This version of fatJar too does not work.
apply plugin: 'java'
repositories {
jcenter()
}
dependencies {
compile (':coregeneral')
testCompile 'junit:junit:4.12'
}
jar {
baseName='corehibernate'
from ('bin')
}
task fatJar(type: Jar, dependsOn: jar) {
baseName = project.name + '-fat'
}
There are two basic ways how to bundle projects together. The first would be to use application plugin which creates a zip with scripts that will also execute your application and bundle all jars by default. Second way is to use distribution plugin and define the final archive yourself (zip or tar).
Here is a sample project using the application plugin:
settings.gradle
rootProject.name = 'root'
include 'partone', 'parttwo'
build.gradle
subprojects {
apply plugin: 'java'
}
partone/build.gradle - this one is empty
parttwo/build.gradle
apply plugin: 'application'
mainClassName = 'Hello'
dependencies {
compile project (':partone')
}
Give that both projects actually have some content (classes), when you run gradle :projecttwo:build it will generate a zip file with executable scripts and both jars bundled inside.
If you prefer to use distribution plugin, change the parttwo/build.gradle to:
apply plugin: 'distribution'
distributions {
main {
contents {
from jar
from (project.configurations.runtime)
}
}
}
dependencies {
compile project (':partone')
}
And again run gradle :parttwo:build. It will create a zip file that contains both jars.

How to configure Gradle to find local SNAPSHOT resource?

I'm trying to do some work with the springfox project which has been broken up into two separate projects: the springfox runtime, and a suite of demos.
In order to investigate the behavior of certain configurations, I need to change the module in springfox/springfox-petstore, and compile that into springfox-demos/springfox-java-swagger.
In springfox, I built and published a new version of springfox-petstore, and validated that it exists correctly in ~/.m2/repository/io/springfox/springfox-petstore/2.2.2-SNAPSHOT.
Next, in springfox-demos I added mavenLocal() as a repository, and added the springfox-petstore-2.2.2-SNAPSHOT as a changing=true dependency.
When I attempt to build the springfox-demos runtime, I get the following error:
* What went wrong:
A problem occurred configuring project ':spring-java-swagger'.
> Could not resolve all dependencies for configuration ':spring-java-swagger:runtimeCopy'.
> Could not find io.springfox:springfox-petstore:2.2.2-SNAPSHOT.
Searched in the following locations:
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/maven-metadata.xml
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.pom
https://jcenter.bintray.com/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.jar
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/maven-metadata.xml
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.pom
http://oss.jfrog.org/artifactory/oss-snapshot-local/io/springfox/springfox-petstore/2.2.2-SNAPSHOT/springfox-petstore-2.2.2-SNAPSHOT.jar
Required by:
springfox-demos:spring-java-swagger:unspecified
I've tried a variety of combinations of build tasks but I can't seem to get Gradle to honor my request for using the local maven repo with a -SNAPSHOT artifact.
Here is the top-level build.gradle:
buildscript {
repositories {
mavenLocal()
jcenter()
}
dependencies {
classpath "com.github.adrianbk:gradle-jvmsrc-plugin:0.6.1"
classpath 'com.ofg:uptodate-gradle-plugin:1.6.0'
}
}
apply from: "$rootDir/gradle/dependencies.gradle"
subprojects {
apply plugin: 'com.github.adrianbk.jvmsrc'
jvmsrc {
packageName "springfoxdemo"
}
apply plugin: 'java'
apply plugin: 'com.ofg.uptodate'
repositories {
jcenter()
maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
configurations.all {
//Dont cache snapshots
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
}
wrapper {
gradleVersion = "2.4"
}
So it appears that the top-level build.gradle can have more than one repositories{} block. I had correctly added the mavenLocal() to one, but missed the other. Once adding the mavenLocal() to the second block, all worked well.

Running Gradle plugin directly from command line

In Maven, if I wanted to analyze my project with sonar, I could do:
mvn sonar:sonar
using the 'short' plugin name and goal.
In Gradle, is there a similar way to run plugins, without declaring them in the build.gradle script?
This code works fine:
allprojects {
buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5"
}
}
apply plugin: 'java'
apply plugin: 'jacoco'
afterEvaluate { project ->
project.apply plugin: 'org.sonarqube'
}
}
gradle --init-script etc/quality.gradle sonarqube
There isn't currently, but there will be at some point. What you can do is to apply the plugin out-of-band (in some init.gradle).

Resources