I\'m using Gradle to build a jar containing an xml file in META-INF
. This file has a row like
I've had similar problems migrating from maven to gradle build. And so far the simplest/easiest solution was to simply do the filtering yourself such as:
processResources {
def buildProps = new Properties()
buildProps.load(file('build.properties').newReader())
filter { String line ->
line.findAll(/\$\{([a-z,A-Z,0-9,\.]+)\}/).each {
def key = it.replace("\${", "").replace("}", "")
if (buildProps[key] != null)
{
line = line.replace(it, buildProps[key])
}
}
line
}
}
This will load all the properties from the specified properties file and filter all the "${some.property.here}" type placeholders. Fully supports dot-separated properties in the *.properties file.
As an added bonus, it doesn't clash with $someVar type placeholders like expand() does. Also, if the placeholder could not be matched with a property, it's left untouched, thus reducing the possibility of property clashes from different sources.
I took your first attempt and created a test project. I put a pom file from a jenkins plugin in ./src/main/resources/META-INF/
. I assume it is a good enough xml example. I replaced the artifactId line to look like the following:
<artifactId>${artifactId}</artifactId>
My build.gradle:
apply plugin: 'java'
jar {
expand project.properties
}
When I ran gradle jar
for the first time it exploded because I forgot to define a value for the property. My second attempt succeeded with the following commandline:
gradle jar -PartifactId=WhoCares
For testing purposes I just defined the property using -P. I'm not sure how you are trying to define your property, but perhaps that is the missing piece. Without seeing the stacktrace of your exception it's hard to know for sure, but the above example worked perfectly for me and seems to solve your problem.
I stumbled across this post in a thread about a different but closely related issue. Turns out you want to configure the processResources
task, not the jar
task:
processResources {
expand project.properties
}
For some reason, though, I did have to clean
once before Gradle noticed the change.
here is what worked for me (Gradle 4.0.1) in a multi-module project:
in /webshared/build.gradle
:
import org.apache.tools.ant.filters.*
afterEvaluate {
configure(allProcessResourcesTasks()) {
filter(ReplaceTokens,
tokens: [myAppVersion: MY_APP_VERSION])
}
}
def allProcessResourcesTasks() {
sourceSets*.processResourcesTaskName.collect {
tasks[it]
}
}
and my MY_APP_VERSION
variable is defined in top-level build.gradle
file:
ext {
// application release version.
// it is used in the ZIP file name and is shown in "About" dialog.
MY_APP_VERSION = "1.0.0-SNAPSHOT"
}
and my resource file is in /webshared/src/main/resources/version.properties
:
# Do NOT set application version here, set it in "build.gradle" file
# This file is transformed/populated during the Gradle build.
version=@myAppVersion@
In addition to @emil-lundberg 's excellent solution, I'd limit the resource processing to just the desired target file:
build.gradle
processResources {
filesMatching("**/applicationContext.xml") {
expand(project: project)
}
}
An additional note: if the ${...}
parentheses are causing "Could not resolve placeholder" errors, you can alternatively use <%=...%>
. N.B. tested with a *.properties
file, not sure how this would work for an XML file.