Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to expand property references in jar resources?

Tags:

gradle

I'm using Gradle to build a jar containing an xml file in META-INF. This file has a row like

<property name="databasePlatform" value="${sqlDialect}" />

to allow for different SQL databases for different environments. I want to tell gradle to expand ${sqlDialect} from the project properties.

I tried this:

jar {
    expand project.properties
}

but it fails with a GroovyRuntimeException that seems to me like the Jar task attempts to expand properties in .class files as well. So then I tried

jar {
    from(sourceSets.main.resources) {
        expand project.properties
    }
}

which does not throw the above exception, but instead results in all resources being copied twice - once with property expansion and once without. I managed to work around this with

jar {
    eachFile {
        if(it.relativePath.segments[0] in ['META-INF']) {
            expand project.properties
        }
    }
}

which does what I want, since in my use case I only need to expand properties of files in the META-INF directory. But this feels like a pretty ugly hack, is there a better way to do this?

like image 739
Emil Lundberg Avatar asked Jun 24 '13 11:06

Emil Lundberg


3 Answers

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.

like image 60
Emil Lundberg Avatar answered Oct 17 '22 04:10

Emil Lundberg


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.

like image 23
Nick Grealy Avatar answered Oct 17 '22 02:10

Nick Grealy


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.

like image 2
Martynas Petuska Avatar answered Oct 17 '22 02:10

Martynas Petuska