首页 > 解决方案 > 使用 gradle 对不同环境进行恒定路径替换

问题描述

这是一个基于 Apache Storm 的项目。我有一个看起来像这样的常量文件

public class Constant {    
    public static final String CONTEXT_PATH ="<some path to a context.xml file>"; 
    public static final String APP_PROPERTIES_PATH = "<path to the properties file>";

    //...More static properties
}

这个 CONTEXT_PATH 变量对于不同的环境(dev、test、prod)是不同的。

我有一个 gradle 任务,它生成用于部署的 JAR 文件

task stormJar(type: Jar) {
    baseName = 'diagnostic'
    from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
    with jar
}

我希望动态更改或引用 CONTEXT_PATH 变量,以便我们可以为不同的环境创建构建,而无需对此文件进行任何更改。

我相信在 Android 领域 (BuildConfig) 有这样做的解决方案,但无法为普通的 Java 项目找到解决方案。

解决方案应该是这样的,它应该适用于 IDE(IntelliJ 和 Eclipse)以及创建特定于环境的构建。

做类似下面的事情应该可以完成工作

gradlew build -pEnvironment=prod

gradle的经验不多。请指出我正确的方向。

标签: javagradle

解决方案


请注意这里有一个工作示例。

一种技术是生成Constants.java作为构建的一部分。考虑这个模板(存储为资源,而不是 Java 代码):

public class Constants {
    public static final String CONTEXT_PATH = "__CONTEXT_PATH";
    public static final String APP_PROPERTIES_PATH = "__APP_PROPERTIES_PATH";
}

并在任务Constants.java早期生成以下内容:compileJava

compileJava.doFirst {
    def newConstantsFile = new File("${projectDir}/src/main/java/net/codetojoy/util/Constants.java")
    def templateConstantsFile = new File("${projectDir}/resources/TemplateConstants.java")

    newConstantsFile.withWriter { def writer ->
        templateConstantsFile.eachLine { def line ->
            def newLine = line.replace("__PACKAGE", "net.codetojoy.util")
                              .replace("__CONTEXT_PATH", getContextPath())
                              .replace("__APP_PROPERTIES_PATH", getAppPropertiesPath())
            writer.write(newLine + "\n");
        }
    }
}

然后是关键的特定于环境的谓词:

def getContextPath = { ->
    def result = "default"

    if (project.Environment == "prod") {
        result = "PROD context path here"
    } else if (project.Environment == "uat") {
        result = "UAT context path here"
    } else if (project.Environment == "dev") {
        result = "DEV context path here"
    }

    return result
}

def getAppPropertiesPath = { ->
    def result = "default"

    if (project.Environment == "prod") {
        result = "PROD app properties path here"
    } else if (project.Environment == "uat") {
        result = "UAT app properties path here"
    } else if (project.Environment == "dev") {
        result = "DEV app properties path here"
    }

    return result
}

请注意,特定于 ENV 的值可以很容易地抽象为配置文件、ENV 变量等。

另请注意,示例地址:package使用的 Java、项目版本和构建时间戳。我为大多数项目写了这样的东西。


推荐阅读