I have a requirement to create spring boot jar file name based upon the environments. The environment can be dev or prod. When I run with the command gradlew clean build, it generates app-service-0.0.1.SNAPSHOT.jar. As per my requirement, it should be app-service-0.0.1.SNAPSHOT.jar for dev environment and app-service-0.0.1.jar for prod environment. How can I customize the naming of spring boot jar file in gradle? Please help me. I have also tried in the following manner, it did not work.
... other gradle code ....
ext {
isProd = System.properties['env'] == 'prod'
isDev = System.properties['env'] == 'dev'
}
//if (isDev) tasks.withType(jar).all { it.enabled = false }
task dev(type: org.springframework.boot.gradle.tasks.bundling.BootJar) {
baseName = 'custom-spring-boot'
/*
bootJar {
archiveFileName = 'my-awesome-app.jar'
}
*/
}
/*
bootJar {
if (env == 'dev') {
archiveFileName = 'my-awesome-app.jar'
} else {
archiveFileName = 'hati-app.jar'
}
}
*/
tasks.addRule("Pattern: bootJar<ENV>") { String taskName ->
if (taskName.startsWith('bootJar')) {
def env = (taskName - 'bootJar').toLowerCase()
if (env in ['dev', 'prod',]) {
task(taskName, type: bootJar) {
println "Configuring env: $env"
from("src/main/conf/$env") {
into("conf")
}
}
} else {
println "Invalid env: $env, skipping."
}
}
}
I also checked with this SO link
Related
This question was answered before but the chosen answer doesn't explain a lot for me on how this is doable on Gradle.
That and the fact that I can't comment on the solution to ask for more info forced me to make this question.
I have a Gradle project that has several modules available and I now want to set up the Javadoc task to combine the Javadoc comments of all the modules into a single location where I could browse it.
How would I now be able to do this using Gradle? I run Gradle 5.5 if the version is of any importance and I have the following things set in the build.gradle file:
allprojects {
ext {
// Convenience method to configure Javadoc
configureJavadoc = { Object jDocConfig ->
jDocConfig.options {
it.author()
it.encoding = 'UTF-8'
it.memberLevel = JavadocMemberLevel.PROTECTED
if (it instanceof StandardJavadocDocletOptions) {
def opt = it as StandardJavadocDocletOptions
opt.links(
"https://docs.example.com/java/"
)
if (JavaVersion.current().isJava9Compatible()) {
opt.addBooleanOption("html5", true)
opt.addStringOption("-release", "8")
}
if (JavaVersion.current().isJava11Compatible()) {
opt.addBooleanOption("-no-module-directories", true)
}
}
}
}
}
}
subprojects {
javadoc {
destinationDir = file("$rootDir/docs/")
configureJavadoc(it)
}
}
I was able to do it with:
def exportedProjects = [
":",
":module-a",
":module-b",
":module-c"
]
task allJavadoc(type: Javadoc) {
source exportedProjects.collect { project(it).sourceSets.main.allJava }
classpath = files(exportedProjects.collect { project(it).sourceSets.main.compileClasspath })
destinationDir = file("${buildDir}/docs/javadoc-all")
}
How do I enable "--enable-preview" for tests in Kotlin-based Gradle script ? I tried literally everything I could find online with https://stackoverflow.com/a/61849770/226895 being the closest to correct answer.
I still get following error on :test task
org.gradle.api.internal.tasks.testing.TestSuiteExecutionException: Could not execute test class 'com.blabla.playground.AppTest'.
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:53)
Caused by: java.lang.UnsupportedClassVersionError: Preview features are not enabled for com/blabla/playground/AppTest (class file version 58.65535). Try running with '--enable-preview'
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
by script is
plugins {
java
application
}
repositories {
jcenter()
}
dependencies {
implementation("com.google.guava:guava:28.2-jre")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0")
}
application {
mainClassName = "com.blabla.playground.App"
}
java {
sourceCompatibility = JavaVersion.VERSION_14
targetCompatibility = JavaVersion.VERSION_14
}
tasks {
withType<Test>().all {
allJvmArgs.add("--enable-preview")
testLogging.showStandardStreams = true
testLogging.showExceptions = true
useJUnitPlatform {
}
}
withType<JavaExec>().all {
jvmArgs!!.add("--enable-preview")
}
withType<Wrapper>().all {
gradleVersion = "6.4.1"
distributionType = Wrapper.DistributionType.BIN
}
withType(JavaCompile::class.java).all {
options.compilerArgs.addAll(listOf("--enable-preview", "-Xlint:preview"))
}
jar {
manifest {
attributes("Main-Class" to "com.blabla.playground.App")
}
}
}
What am I missing?
It turned out that the way you are configuring the flag for Test tasks does not really append the flag to allJvmArgs.
I managed to made it work by configuring the Test tasks like so :
withType<Test>().all {
jvmArgs("--enable-preview")
}
or
withType<Test>().all {
allJvmArgs = listOf("--enable-preview")
}
However the second option might not be preferable as it substitutes all JVM arguments for forked process (including arguments to define system properties, the minimum/maximum heap size, and the bootstrap classpath). The first option should be preferrable.
One of my plugins uses the files created by the gradle build of another project.
However gradle evaluates the plugin task before building. Is there a way to make the plugin tasks be created after the build is completed?
EDIT:
Here is the build.gradle
apply plugin: 'confluence-export'
sourceSets {
tools
}
compileToolsJava {
source += sourceSets.main.java
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
dependencies {
toolsCompile files("${System.getProperty('java.home')}/../lib/tools.jar")
}
task generateTagDoc(type: JavaExec) {
classpath = sourceSets.tools.runtimeClasspath
main = 'TagsDocumentation'
outputs.upToDateWhen { false }
}
task generateTypeDoc(type: Javadoc) {
classpath = sourceSets.tools.runtimeClasspath
source = sourceSets.main.allJava
options.docletpath = compileToolsJava.outputs.files.asList()
options.doclet = "ExtractCommentsDoclet"
options.addStringOption("Tags.java")
outputs.upToDateWhen { false }
}
confluence {
spaceKey = *****
exportAll = true
title = *******
exportUser = "******
exportPassword = ******
libraryName = ******
host = ********
}
asciidoctor {
resources {
from(sourceDir) {
include 'img/**'
}
}
}
asciidoctor.dependsOn(generateTagDoc)
generateTagDoc.dependsOn(generateTypeDoc)
generateTypeDoc.dependsOn(compileToolsJava)
So here I want my build to run which will create a folder asciidoc/html5 in the build folder with all my created html pages from my asciidoc files. My plugin goes through each file and creates a task for it and then uploads it to a website. The problem is the plugin task is evaluated before the build so the folder asciidoc/html5 hasn't been created yet. If i add a check to see if the folder has been created it will indeed remove my error however the task will still be empty. This is why i would like to know if there is a way for the plugin tasks to be created after the build is done so that the folder is created.
EDIT 2:
Here is the plugin creation:
class ConfluenceExportPlugin extends ConfluencePluginBase implements Plugin<Project> {
#Override
void apply(Project project) {
def confluenceExtension = project.extensions.create('confluence', ConfluenceExtension)
project.afterEvaluate {
if (confluenceExtension.exportAll) {
def list = []
def dir = new File("${project.buildDir}/asciidoc/html5")
if(dir.exists() && dir.isDirectory())
dir.eachFileRecurse(FileType.FILES) {
if(it.name.endsWith('.html')) {
list.add(it)
}
}
Task mainTask = project.task('confluenceExport')
mainTask.dependsOn("build")
list.each { file ->
def curName = file.name.take(file.name.lastIndexOf('.'))
ConfluenceExportTask subTask = createTask(project, "confluenceExport${curName}", confluenceExtension, file.path, curName)
mainTask.dependsOn(subTask)
}
}
else {
ConfluenceExportTask task = createTask(project, "confluenceExport", confluenceExtension, getManFile(confluenceExtension, project), confluenceExtension.title)
}
}
}
ConfluenceExportTask createTask(Project project, String taskName, def confluenceExtension, manFile, String pageTitle ){
ConfluenceExportTask task = project.task(type: ConfluenceExportTask, taskName)
task.conventionMapping.map "user", { confluenceExtension.user }
task.conventionMapping.map "password", { confluenceExtension.password }
task.conventionMapping.map "spaceKey", { confluenceExtension.spaceKey }
task.conventionMapping.map "manFile", { manFile }
task.conventionMapping.map "pageTitle", { pageTitle }
task
}
String getManFile(ConfluenceExtension configuration, Project project) {
configuration.exportSourceFilePath ?: "${project.buildDir}/asciidoc/html5/${configuration.libraryName}.html"
}
}
Here's my first attempt at a C program built with Gradle's C plugin:
apply plugin: 'c'
model {
components {
derpus(NativeExecutableSpec) {
sources {
c(CSourceSet) {
source {
srcDir "src/derpus/c"
include "**/*.c"
}
exportedHeaders {
srcDir "src/derpus/headers"
}
}
}
}
}
}
This produces an executable called derpus.exe. I would like, if at all possible, to version these executables (derpus-1.0.0.exe, derpus-1.0.1.exe, etc.). When I change the derpus closure to derpus-1.0.0 like so:
derpus-1.0.0(NativeExecutableSpec) {
And run gradle clean build I get:
D:\workspace\derp\20150505\derpus>gradlew clean build
FAILURE: Build failed with an exception.
* Where:
Build file 'D:\derpus\build.gradle' line: 6
* What went wrong:
Could not compile build file 'D:\derpus\build.gradle'.
> startup failed:
build file 'D:\derpus\build.gradle': 6: unexpected tok
en: 0 # line 6, column 20.
derpus-1.0.0(NativeExecutableSpec) {
^
1 error
Does anybody know of a way to version these executables?
Update
Now this is really weird! Taking Amnon's advice, I added a gradle.properties file that defined version=1.0.0. I then modified my model closure to:
model {
components {
derpus(NativeExecutableSpec) {
sources {
c(CSourceSet) {
source {
srcDir "src/derpus/c"
include "**/*.c"
}
exportedHeaders {
srcDir "src/derpus/headers"
}
}
}
baseName = "derpus-${version}"
}
}
}
This produces an executable named derpus-1 (what?!?!)!
So then I modified model again:
version = "3.4"
model {
components {
derpus(NativeExecutableSpec) {
sources {
c(CSourceSet) {
source {
srcDir "src/derpus/c"
include "**/*.c"
}
exportedHeaders {
srcDir "src/derpus/headers"
}
}
}
baseName = "derpus-${version}"
}
}
}
As you can see, this should overrdide the version set in gradle.properties, however after running gradle clean build, it produces derpus-3!
So I modified model yet again:
model {
components {
derpus(NativeExecutableSpec) {
sources {
c(CSourceSet) {
source {
srcDir "src/derpus/c"
include "**/*.c"
}
exportedHeaders {
srcDir "src/derpus/headers"
}
}
}
baseName = "derpus-3.4.5"
}
}
}
This produces derpus-3.4!!! What is going on here?!? Does the C plugin have a bug in it that doesn't honor the full version variable?
In your example above the problem with derpus-1.0.0 is the gradle things that the dash character is a minus which is unexpected in a component spec name, thus the failure. You can overcome this by wrapping derpus-1.0.0 with inverted commas. A better approach, however, would be to apply the version to the baseName property of the component spec, i.e. add the following line under derpus component definition:
baseName = "derpus-1.0.0"
or
baseName = "derpus-$version"
Where in the second case the version property $version is taken from the project object.
Update
Per smeeb comments below another workaround that can be applied is to directly rename the target binaries:
afterEvaluate {
RenameNativeBinaries()
}
def RenameNativeBinaries() {
binaries.all { b ->
if (b instanceof SharedLibraryBinarySpec) {
b.sharedLibraryFile = ReconstructFileName(b.sharedLibraryFile)
} else if (b instanceof StaticLibraryBinarySpec) {
b.staticLibraryFile = ReconstructFileName(b.staticLibraryFile)
}
}
}
def ReconstructFileName(File originalFile) {
def originalFileName = originalFile.absolutePath
def filePath = FilenameUtils.getFullPath(originalFileName)
def baseName = FilenameUtils.getBaseName(originalFileName)
def extension = FilenameUtils.getExtension(originalFileName)
def newName = "$baseName-$version.$extension"
def newFile = new File(filePath, newName)
newFile
}
Where FilenameUtils is taken from commons-io:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-io', name: 'commons-io', version: '2.4'
}
}
I use a third-party Gradle plugin in a lot of projects and would like to add this plugin permanently to my gradle installation. Currently I need to add the plugin to each build.gradle like so:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.github.dcendents:android-maven-plugin:1.2"
}
}
Is there a way to add this plugin to my Gradle installation so that I don't need to include it in every build file?
I do realise it might not be the best practice and can result in unreproducible builds.
This is a hack and not a solution
Here is now an updated version which is also able to apply plugins and add maven repositories. Testet with gradle 2.10.
Add this Plugin to your .gradle/init.gradle:
apply plugin:AddDepPlugin
class AddDepPlugin implements Plugin<Gradle> {
def addDeps = [
"org.ensime.gradle": "gradle.plugin.net.coacoas.gradle:ensime-gradle:0.2.2",
"com.github.dcendents.android-maven": "com.github.dcendents:android-maven-plugin:1.2"]
def addRepos = ["https://plugins.gradle.org/m2/"]
void apply(Gradle gradle) {
def add = 0
gradle.allprojects { project ->
plugins.whenPluginAdded { t ->
if (++add == 1) {
project.getBuildScriptSource()
def bs = project.getBuildscript()
bs.getDependencies()
def repo = bs.getRepositories()
def ccf = bs.class.getDeclaredField("classpathConfiguration")
ccf.setAccessible(true)
def cc = ccf.get(bs)
addDeps.each { k,v-> cc.dependencies.add(project.dependencies.create(v))}
addRepos.each { k-> repo.maven { -> setUrl(k) } }
}
if (add == 8)
addDeps.each { k,v ->
if (!k.startsWith("x")) project.apply([plugin: k])
}
}
}
}
}
On http://ensime.github.io//build_tools/gradle/ I found this alternative solution (this is for the ENSIME plugin):
apply plugin: AddEnsimePlugin
class AddEnsimePlugin implements Plugin<Gradle> {
def supportedPlugins = [
'org.gradle.api.plugins.JavaPlugin',
'org.gradle.api.plugins.ScalaPlugin',
'jp.leafytree.gradle.AndroidScalaPlugin'
]
void apply(Gradle gradle) {
def added = false
gradle.allprojects { project ->
project.with {
if (parent == null) {
buildscript {
repositories {
jcenter()
maven {
name 'JFrog OSS Snapshot Repository'
url 'http://oss.jfrog.org/oss-snapshot-local'
}
}
dependencies {
classpath 'net.coacoas.gradle:ensime-gradle:0.2.6'
}
}
}
plugins.whenPluginAdded { plugin ->
if (!added && supportedPlugins.contains(plugin.class.name)) {
rootProject.apply plugin: 'org.ensime.gradle'
added = true
}
}
}
}
}
}
It works for me with Gradle 2.12. The other answer also works for me.