8

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

<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目录中文件的属性。但这感觉就像一个非常丑陋的黑客,有没有更好的方法来做到这一点?

4

5 回答 5

10

我在一个关于另一个但密切相关的问题的线程中偶然发现了这篇文章。原来你想配置processResources任务,而不是jar任务:

processResources {
    expand project.properties
}

clean不过,出于某种原因,在 Gradle 注意到变化之前,我确实必须这样做一次。

于 2013-06-24T12:56:34.153 回答
9

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

构建.gradle

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

附加说明:如果${...}括号导致“无法解析占位符”错误,您也可以使用<%=...%>. NB*.properties文件进行了测试,不确定这对 XML 文件如何工作。

于 2016-04-19T23:31:15.853 回答
2

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

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 类型的占位符发生冲突。此外,如果占位符无法与属性匹配,则保持不变,从而减少来自不同来源的属性冲突的可能性。

于 2018-02-27T13:36:45.777 回答
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@
于 2017-07-09T05:55:08.457 回答
0

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

<artifactId>${artifactId}</artifactId>

我的 build.gradle:

apply plugin: 'java'

jar {
    expand project.properties
}

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

 gradle jar -PartifactId=WhoCares

出于测试目的,我刚刚使用 -P 定义了该属性。我不确定你是如何定义你的财产的,但也许那是缺失的部分。如果没有看到异常的堆栈跟踪,很难确定,但上面的例子对我来说非常有效,似乎解决了你的问题。

于 2013-06-24T12:53:36.860 回答