How do I add a .properties file into my WAR using gradle? - gradle

WAR
- META-INF
- WEB-INF
- classes
- META-INF
- myApp.properties <-- Needs added
How do I add a .properties file into my WAR using gradle?
The file was later introduced into the project but doesn't
get added?
build.gradle
import org.apache.commons.httpclient.HttpClient
import org.apache.commons.httpclient.methods.GetMethod
group = 'gradle'
version = '1.0'
apply plugin: 'war'
apply plugin: 'jetty'
apply plugin: 'eclipse'
eclipseProject
{
projectName = 'crap'
}
defaultTasks 'build'
dependencies
{
//all my dependencies
}
war
{
classpath fileTree('lib')
}
jar.enabled = true
[jettyRun, jettyRunWar]*.daemon = true
stopKey = 'stoppit'
stopPort = 9451
httpPort = 8080
scanIntervalSeconds = 1

war {
from('<path-to-props-file>') {
include 'myApp.properties'
into('<target-path>')
}
}

Something like this should work:
war {
from('<path-to-props-file>') {
include 'myApp.properties'
}
}
If you want to specify which directory you want the properties file to be located in:
war {
from('<path-to-props-file>') {
include 'myApp.properties'
into('<targetDir>')
}
}

eg1:
war {
webInf{
from('PATH_TO_SOURCE_FOLDER') {
include 'FILE_TO_BE_INCLUDED'
into('TARGET_FOLDER_RELATIVE_TO_WEB_INF_DIR')
}
}
}
eg2:
war {
webInf{
from('src/META-INF') {
include 'persistence.xml'
into('classes/META-INF/')
}
}
}
For more information check the online documentation: Chapter 26. The War Plugin

I normally use an environments folder from which I pick a given configuration file based on the deploy variable. Ex.:
from("environments/system.${env}.properties"){
include "system.${env}.properties"
into 'WEB-INF'
rename("system.${env}.properties", 'system.properties')
}
the property is passed through gradle as:
./gradlew buildDocker -Penv=prod

Related

How to set packaging to pom in Gradle instead of defaulting to jar

I have a project that generates a Bill of Materials (BOM). When I execute gradle build it generates an empty jar, containing only a META-INF folder.
However I am able to publish the pom (BOM) to Nexus correctly, with the side effect of also uploading the empty jar.
According to the maven plugin doc https://docs.gradle.org/current/userguide/maven_plugin.html we should be able to set the packaging:
packaging archiveTask.extension
Here, uploadTask and archiveTask refer to the tasks used for uploading
and generating the archive
How can I set the packaging to pom?
Example of Gradle uploaded pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ttt.a</groupId>
<artifactId>my-bom</artifactId>
<version>Something-SNAPSHOT</version>
When I upload it with maven instead of gradle, there is an additional:
<packaging>pom</packaging>
UPDATE:
Full build.gradle config:
buildscript {
repositories {
maven {
url "http://myrepo"
}
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:1.0.4.RELEASE"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.5"
classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7'
} }
apply plugin: 'java' apply plugin: 'maven' apply plugin: "io.spring.dependency-management" apply plugin: "jacoco" apply plugin: 'org.asciidoctor.convert' apply plugin: 'org.sonarqube'
group = project.properties['groupId'] version = project.properties['version'].toString()
description = """Bill of Materials"""
sourceCompatibility = 1.8 targetCompatibility = 1.8
ext {
xxx = '1.0.0'
yyy = '1.2.0'
... }
repositories {
maven {
url "http://myrepo"
} }
dependencyManagement {
dependencies {
dependency "com.myorg:xxx:${xxx}"
dependency "com.myorg:yyy:${yyy}"
...
} }
uploadArchives {
repositories {
mavenDeployer {
snapshotRepository(url: 'http://myrepo') {
authentication(userName: "$System.env.NEXUS_USER", password: "$System.env.NEXUS_PASSWORD")
}
}
} }
asciidoctor {
sourceDir = file('src/docs/asciidoc/')
sources {
include '*.adoc'
}
outputDir = file("build/docs/${version}") }
task generateDummyBom {
doLast {
project.buildDir.mkdirs()
new File("$project.buildDir/dummy.pom").write("<project></project>\n")
}
ext.bomFile = file("$project.buildDir/dummy.pom") }
artifacts {
archives(generateDummyBom.bomFile) {
builtBy generateDummyBom
} }
jar.enabled = false
I found that the maven plugin seems to ignore the packaging property. After some experimentation, I found that it sets the packaging property to the extension of the file in your artifact. So, the way to get the packaging property set to pom is to create a dummy artifact with a file having a .pom extension, as below.
// The real file that we want to publish is the pom generated implicitly by the
// maven publishing plugin.
//
// We need to generate at least one file that we can call an archive so that the
// maven plugin will actually publish anything at all. Luckily, if the file
// that we call an archive is a .pom file, it's magically discarded, and we are
// only left with the implicitly-generated .pom file.
//
// We need the extension of the file to be `.pom` so that the maven plugin will
// set the pom packaging to `pom` (i.e. `<packaging>pom</packaging>`). Otherwise,
// packaging would be set to `xml` if our only file had an `.xml` extension.
task generateDummyBom {
doLast {
// Since we don't depend on anything else, we have to create the build dir
// ourselves.
project.buildDir.mkdirs()
// The file actually has to have xml in it, or Sonatype will reject it
new File("$project.buildDir/${project.artifactId}.pom").write("<project></project>\n")
}
ext.bomFile = file("$project.buildDir/${project.artifactId}.pom")
}
artifacts {
archives(generateDummyBom.bomFile) {
builtBy generateDummyBom
}
}
jar.enabled = false
Update: If you apply the java plugin, you will need to remove the jar archive from your archives.
// Remove the default jar archive which is added by the 'java' plugin.
configurations.archives.artifacts.with { archives ->
def artifacts = []
archives.each {
if (it.file =~ 'jar') {
// We can't just call `archives.remove(it)` here because it triggers
// a `ConcurrentModificationException`, so we add matching artifacts
// to another list, then remove those elements outside of this iteration.
artifacts.add(it)
}
}
artifacts.each {
archives.remove(it)
}
}
Second update: Replaced "dummy.pom" with "${project.artifactId}" above.
I couldn't get Garrett's solution to work, but I did have success like this:
dependencies {
// ...Omitted...
}
tasks.named('generatePomFileForMavenJavaPublication') {
pom.with {
description = 'Parent BOM'
withXml {
// ...Omitted...
}
}
}
// Removing all jar artifacts from the mavenJava publication
// appears to automagically cause packaging to be set to 'pom'!
publishing.publications.named('mavenJava') {
artifacts.removeIf { artifact ->
artifact.extension == 'jar'
}
}

How to specify output.classesDir for custom sourceSet in Gradle?

My build uses source code from two projects: ProjectA and ProjectB, and produces JAR with classes and resources from ProjectB. I defined custom sourceSet mainProjectB which is supposed to have output in a separate directory:
sourceSets {
mainProjectB {
output.classesDir = "$buildDir/build/classes/projectB"
output.resourcesDir = "$buildDir/build/resources/projectB"
java { srcDirs = ['src/main/java']}
resources { srcDirs = ['src/main/resources']}
}
mainProjectA {
java { srcDirs = [
'../projectA/src/main/java'
]}
resources { srcDirs = [
'../projectA/src/main/resources'
]}
}
test {
java {
srcDirs = [
'../projectA/src/test/java',
'src/test/java'
]}
resources {
srcDirs = [
'../projectA/src/test/resources',
'src/test/resources'
]}
}
}
compileJava {
source sourceSets.mainProjectB.allJava
source sourceSets.mainProjectA.allJava
}
processResources {
from sourceSets.mainProjectB.resources
from sourceSets.mainProjectA.resources
}
jar {
from sourceSets.mainProjectB.output.classesDir
from sourceSets.mainProjectB.output.resourcesDir
}
Problem: custom sourceSet mainProjectB ingores specified output directories.
The directories "$buildDir/build/classes/projectB" and "$buildDir/build/resources/projectB" are not created, and as a consequence, JAR includes files from both projects (instead of ProjectB).
UPDATE:
Projects A and B have circular dependencies. That is why they have to share source code.
I would consider to use subprojects and project to achieve your goal - gradel docs . With the following approach you can get any kind of jar file depending on your build :
group 'CoreProject'
version '1.0-SNAPSHOT'
subprojects {
apply plugin: 'java'
repositories {
mavenCentral()
}
}
project (':projectA') {
}
project (':projectB') {
def generatedResources = "$buildDir"
//in case you want resources and classes to be written to custom location where
//redefined paths are relative to projectB root folder
sourceSets {
main {
output.classesDir = 'build/classes/projectB'
output.resourcesDir = 'build/resources/projectB'
}
}
dependencies {
compile project(':projectA')
}
jar {
manifest.mainAttributes(
'Main-Class': "ProjectBClass"
)
}
//To create fat Jar that will contain classes and resources from all dependencies
task fatJar(type: Jar) {
manifest.from jar.manifest
classifier = 'all'
from {
configurations.runtime.collect { it.isDirectory() ? it : zipTree(it) }
} {
exclude "ProjectAResource" //if want to exclude resources from projectA
exclude "META-INF/*.SF"
exclude "META-INF/*.DSA"
exclude "META-INF/*.RSA"
}
with jar
}
}
If you run jar task of projectB following jars will be created, each including only its own classes and resources : projectA/build/libs/projectA.jar , projectB/build/libs/projectB.jar('JAR with classes and resources from ProjectB' as you asked in your comment)
If you run farJar task of projectB the following jar file will be created that includes classes and resources from both projects and you can exclude any files patterns from projectA and projectB projects to create any final jar you like : projectB/build/libs/projectB-all.jar
Here is a screenshot of projects folders structure I created to mimic your scenario(as I understood it):
P.S. Also make sure none of the folders projectB/build and projectA/build are locked by any process and remove those handles if any, as otherwise Gradle will fail to run.

Gradle war command not including hibernate cfg file

Hibernate-cfg.xml not added to war classes folder.I am using below script to deploy web applcation to tomcat.After copy, when i am starting tomcat , gettign below error
eNotFoundException: class path resource [hibernate.cfg.xml] cannot be resolved URL because it does not exist
apply plugin: 'java'
apply plugin: 'war'
sourceCompatibility = 1.7
apply plugin: 'eclipse'
repositories {
mavenCentral()
}
dependencies {
compile("javax.servlet:jstl:1.2")
compile("org.springframework:spring-context:4.0.3.RELEASE")
compile("org.springframework:spring-webmvc:4.0.3.RELEASE")
compile("org.springframework:spring-web:4.0.3.RELEASE")
compile("org.springframework:spring-aop:4.0.3.RELEASE")
compile("org.springframework:spring-aspects:4.0.3.RELEASE")
compile("org.springframework:spring-beans:4.0.3.RELEASE")
compile("org.springframework:spring-core:4.0.3.RELEASE")
compile("org.springframework:spring-expression:4.0.3.RELEASE")
compile("org.springframework:spring-jdbc:4.0.3.RELEASE")
compile("org.springframework:spring-orm:4.0.3.RELEASE")
compile("org.eclipse.persistence:javax.persistence:2.0.0")
compile("antlr:antlr:2.7.7")
compile("commons-logging:commons-logging:1.1.1")
compile("org.hibernate:hibernate-commons-annotations:3.2.0.Final")
compile("org.hibernate:hibernate-core:4.3.5.Final")
compile("org.apache.derby:derbyclient:10.12.1.1")
compile("javax.validation:validation-api:1.0.0.GA")
compile("org.slf4j:slf4j-api:1.7.5")
}
task deploy (dependsOn: war){
copy {
from "build/libs"
into "C:/soft/apache-tomcat-7.0.67/webapps"
include "*.war"
}
}
/*task startTomcat(dependsOn:deploy,type:Exec) {
workingDir "C:/mdi/soft/apache-tomcat-7.0.67/bin"
commandLine 'cmd', '/c', 'startup.bat'
}*/
task startTomcat << {
def processBuilder = new ProcessBuilder(['cmd','/c','startup.bat'])
processBuilder.directory(new File("C:/soft/apache-tomcat-7.0.67/bin"))
processBuilder.start()
}
// Set source directory
// War file name
war
{
war.baseName = 'userregisteration'
project.webAppDirName = 'WebContent'
sourceSets{
main {
java {
srcDir 'src'
}
}
}
}
In your war task add a from closure:
from(<directory containing Hibernate-cfg.xml>){
into <'directory in the war in which you'd like the file to be placed'>
include 'Hibernate-cfg.xml'
}
This is also pretty basic. I'd recommend perhaps reviewing the Gradle manual again to gain a better understanding of working with files.

Not Publishing the mentioned file(war/tar/zip) to artifactory in gradle script

I wrote a gradle script where I am creating the zip and war file and then I need to upload/publish it to the artifactory but the issue is I specified the war file in my artifact task even after that it is publishing everything to the artifactory zip,tar and war instead of only war file.
apply plugin: 'war'
apply plugin: 'java'
apply plugin: 'distribution'
//-- set the group for publishing
group = 'com.xxx.discovery'
/**
* Initializing GAVC settings
*/
def buildProperties = new Properties()
file("version.properties").withInputStream {
stream -> buildProperties.load(stream)
}
//add the jenkins build version to the version
def env = System.getenv()
if (env["BUILD_NUMBER"]) buildProperties.coveryadBuildVersion += "_${env["BUILD_NUMBER"]}"
version = buildProperties.coveryadBuildVersion
println "${version}"
//name is set in the settings.gradle file
group = "com.aaa.covery"
version = buildProperties.discoveryadBuildVersion
println "Building ${project.group}:${project.name}:${project.version}"
repositories {
maven {
url "http://cxxxxt.tshaaaaa.tho.com:9000/artifactory/libselease"
}
maven {
url "http://cxxxxt.tshaaa.tho.com:9000/artifactory/cache"
}
}
dependencies {
compile ([
"com.uters.omni:HermesSessionAPI:1.2",
"com.uters.proxy:ProxyResources:1.1",
"com.uters.omni:SeshataDirectory:1.0.1" ,
"com.euters.omni:CybeleInfrastructure:1.1.2",
"com.euters:JSONBus:1.4.1",
"javaee:javaee-api:5"
])
}
distributions {
main {
contents {
from {
war.outputs
}
}
}
}
// for publishing to artifactory
artifacts {
archives war
}
According to gradle distribution plugin documentation:
All of the files in the “src/$distribution.name/dist” directory will automatically be included in the distribution.
And also,
The distribution plugin adds the distribution archives as candidate for default publishing artifacts.
In other words, by default all the files will be published so this explains the behavior you're experiencing.
What you can probably do in order to workaround this behavior is to define the contents copySpec more accurately by explicitly exclude the unwanted files, i.e.:
distributions {
main {
contents {
exclude('**/.zip')
exclude('**/.tar')
from {
war.outputs
}
}
}
}
Note that I didn't try the above by myself though so some fine tuning might be needed. However I believe that you can find the data you need in the CopySpec Interface documentation

Is it possible to customise the source sets used by the Gradle license plugin?

buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.6.0'
}
}
apply plugin: 'license'
license {
sourceSets {
main {
java {
exclude '**'
}
test {
exclude '**'
}
}
}
mapping {
javascript='JAVADOC_STYLE'
xml='XML_STYLE'
xsl='XML_STYLE'
html='XML_STYLE'
Rptdesign='XML_STYLE'
}
}
I have read that by default license is added to all sourceSets created by Java Plugin.to customise sourceSets - when i add sourceSets license is not adding to .java files,when i remove sourceSets block license is updating all .java,.groovy files in src/main/ test & java directiries but i have to add license for specfic files like .xml,.xsl at root directory and some specific java files like which starts with s*.java, can any one helpme.
I had the same problem and I found a solution here : https://github.com/hierynomus/license-gradle-plugin/issues/9
You can add the following to your build.gradle and then the license plugin skips the excluded files.
import nl.javadude.gradle.plugins.license.License
tasks.withType(License).each { licenseTask ->
licenseTask.exclude '/*.json'
licenseTask.exclude '/*.properties'
}
( and remove license { sourceSets { ... } })

Resources