如何在jar资源中扩展属性引用?

时间:2013-06-24 11:14:03

标签: gradle

我正在使用Gradle在META-INF中构建一个包含xml文件的jar。这个文件有一行像

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

允许针对不同环境使用不同的SQL数据库。我想告诉gradle从项目属性中扩展${sqlDialect}

我试过了:

jar {
    expand project.properties
}

但它失败并且GroovyRuntimeException在我看来就像Jar任务试图扩展.class文件中的属性一样。所以我试过

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

不会抛出上述异常,而是会导致所有资源被复制两次 - 一次是属性扩展而一次是没有。我设法用

来解决这个问题
jar {
    eachFile {
        if(it.relativePath.segments[0] in ['META-INF']) {
            expand project.properties
        }
    }
}

这就是我想要的,因为在我的用例中我只需要扩展META-INF目录中的文件属性。但这感觉就像一个非常丑陋的黑客,有更好的方法吗?

5 个答案:

答案 0 :(得分:10)

我偶然发现this post在一个关于一个不同但密切相关的问题的帖子中。事实证明,您要配置processResources任务,而不是jar任务:

processResources {
    expand project.properties
}

出于某种原因,在Gradle注意到更改之前,我确实需要clean一次。

答案 1 :(得分:9)

除了@ emil-lundberg的优秀解决方案之外,我还将资源处理限制在所需的目标文件中:

<强> 的build.gradle

processResources {
    filesMatching("**/applicationContext.xml") {
        expand(project: project)
    }
}

另外需要注意:如果${...}括号导致&#34;无法解决占位符&#34; 错误,您也可以使用<%=...%> N.B。使用*.properties文件进行了测试,但不确定这对XML文件的效果如何。

答案 2 :(得分:2)

我在从maven迁移到gradle构建时遇到了类似的问题。到目前为止,最简单/最简单的解决方案是自己简单地进行过滤,例如:

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
  }
}

这将加载指定属性文件中的所有属性,并过滤所有“$ {some.property.here}”类型占位符。完全支持* .properties文件中的点分隔属性。

作为一个额外的好处,它不会与像expand()那样的$ someVar类型的占位符冲突。此外,如果占位符无法与属性匹配,则保持不变,从而减少来自不同来源的财产冲突的可能性。

答案 3 :(得分:1)

这是多模块项目中对我有用的东西(Gradle 4.0.1):

/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]
    }
}

和我的MY_APP_VERSION变量在顶级build.gradle文件中定义:

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"
}

我的资源文件位于/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@

答案 4 :(得分:0)

我第一次尝试并创建了一个测试项目。我在./src/main/resources/META-INF/的jenkins插件中放了一个pom文件。我认为它是一个足够好的xml示例。我将artifactId行替换为如下所示:

<artifactId>${artifactId}</artifactId>

我的build.gradle:

apply plugin: 'java'

jar {
    expand project.properties
}

当我第一次运行gradle jar时,它爆炸了,因为我忘了为属性定义一个值。我的第二次尝试使用以下命令行成功:

 gradle jar -PartifactId=WhoCares

出于测试目的,我只使用-P定义了属性。我不确定你是如何试图定义你的财产,但也许这是缺少的一块。没有看到你的异常的堆栈跟踪,很难确定,但上面的例子对我来说非常合适,似乎可以解决你的问题。