【发布时间】:2013-12-04 22:34:15
【问题描述】:
我想为 Java 项目使用 Gradle 任务生成 Java 类,类似于 Android 插件使用 buildConfig <String> 表示法创建 BuildConfig.java 的方式,例如:
android {
...
buildTypes {
final String PROVIDER_AUTHORITY_RELEASE = "public static final String PROVIDER_AUTHORITY = \"com.example.project.ContentProvider\";\n";
final String PROVIDER_AUTHORITY_DEBUG = "public static final String PROVIDER_AUTHORITY = \"com.example.project.debug.ContentProvider\";\n";
debug {
...
buildConfig PROVIDER_AUTHORITY_DEBUG
}
release {
...
buildConfig PROVIDER_AUTHORITY_RELEASE
}
}
}
用例是我正在开发一个需要使用 API 密钥和秘密的开源应用程序;我在gradle.properties 中拥有未提交给我的 VCS 的密钥和秘密。
到目前为止,我有这个:
task generateSources {
outputDir = file("$buildDir/../src/main/java/uk/co/ataulm/mijur/core/api")
outputs.dir outputDir
doFirst {
outputDir.exists() || outputDir.mkdirs()
String API_CLIENT_ID = "public static final String API_CLIENT_ID = \"<your imgur uk.co.ataulm.mijur.core.api client id>\";\n"
String API_CLIENT_SECRET = "public static final String API_CLIENT_SECRET = \"<your imgur uk.co.ataulm.mijur.core.api client secret>\";\n"
try {
API_CLIENT_ID = "public static final String API_CLIENT_ID = \"" + apiClientId + "\";\n"
API_CLIENT_SECRET = "public static final String API_CLIENT_SECRET = \"" + apiClientSecret + "\";\n"
} catch (Exception e) {
println "gradle.properties not set with apiClientId and/or apiClientSecret. API calls will not work.";
}
new File(outputDir, "ApiConstants.java").write("package uk.co.ataulm.mijur.core.api;\n\npublic class ApiConstants {\n" + " " + API_CLIENT_ID + " " + API_CLIENT_SECRET + "}")
}
}
compileJava.source generateSources.outputs.files, sourceSets.main.java
它可以工作 - 它在指定位置生成该文件。但它非常脆弱;显式命名包容易出错。如果文件是在其他包中生成的(例如在src/main/java 的根目录),我会很高兴,只要我可以使用MyGeneratedFile.MyConstant 在Java 中访问它。
欣赏任何想法(即使它们走的是不同的轨道)。
【问题讨论】:
-
您为什么不简单地使用带有占位符的属性文件,在构建时替换为实际值,并在运行时由您的类加载?
-
@JBNizet 在构建时被替换 - 比如它第一次被访问的时候?通过让 gradle 为我生成它,我可以为每种构建风格提供不同的配置。
-
我也在考虑同样的方法,但对基于 Gradle 的解决方案非常感兴趣。
-
“在构建时”,我的意思是“通过 Gradle”。在我看来,只过滤属性文件比在构建期间生成 Java 文件更容易和自然。
-
我看不出将占位符值放在属性文件中会有什么帮助;鉴于构建脚本是受版本控制的,实际值不应该在属性中吗?