У меня есть веб-сервис, закодированный на kotlin и управляемый gradle для сборки / зависимостей и т. д.
Я хочу сделать простую вещь: когда кто-то вызывает конечную точку version
REST моего веб-сервиса, он возвращает версию.
Поскольку gradle уже обрабатывает версию со свойствами version
в build.gradle
, я подумал, что будет легко получить это значение, но похоже, что это не так ... Я часами искал в Google, и все кажется таким сложным.
Есть идеи, как правильно обращаться с версией?
Вот что у меня есть прямо сейчас:
build.gradle
version = "1.0.0"
...
StatusService.kt
class StatusService : IStatusService {
//TODO: Here I would like to get the version from the gradle
//file instead of maintaining 2 places for the version
//Something like Gradle.getProperties("version") for example
override fun getVersion() : String = "1.0.0"
}
Я могу ошибаться в этом, поэтому, если у вас есть другое эквивалентное решение, я тоже его приму! Спасибо
Почему бы вам просто не написать версию прямо в исходный код через gradle, используя filter(ReplaceTokens...)
?
@xuesheng Никогда не слышал об этом методе. Не стесняйтесь добавлять возможный ответ ниже.
Gradle присутствует только при компиляции, а не во время выполнения.
Для этого вам нужно сгенерировать класс во время компиляции.
В проекте Android
создается файл BuildConfig.java
, но я не знаю, Gradle это или Android.
Для генерации кода Kotlin вы можете проверить КотлинПоэт.
Один из подходов к этому - вывести файл версии как часть вашей сборки Gradle в место в вашем пути к классам, доступное как ресурс в вашем приложении.
Например:
Вы можете добавить это в свой файл build.gradle, который сгенерирует файл свойств, содержащий номер версии проекта, и добавит его в исходный набор приложений, чтобы он был доступен в пути к классам.
def generatedVersionDir = "${buildDir}/generated-version"
sourceSets {
main {
output.dir(generatedVersionDir, builtBy: 'generateVersionProperties')
}
}
task generateVersionProperties {
doLast {
def propertiesFile = file "$generatedVersionDir/version.properties"
propertiesFile.parentFile.mkdirs()
def properties = new Properties()
properties.setProperty("version", rootProject.version.toString())
propertiesFile.withWriter { properties.store(it, null) }
}
}
processResources.dependsOn generateVersionProperties
Затем в своем коде вы сможете получить к нему доступ, прочитав файл свойств:
class StatusService : IStatusService {
private val versionProperties = Properties()
init {
versionProperties.load(this.javaClass.getResourceAsStream("/version.properties"))
}
override fun getVersion() : String = versionProperties.getProperty("version") ?: "no version"
}
Конечно, вам может показаться более простым и подходящим просто вывести String в файл версии, а затем прочитать весь файл как String в вашем коде вместо использования файла свойств.
Спасибо за ответ. Я попробую это!
Первый раздел работает отлично, файл создается в папке сборки. К сожалению, я не могу загрузить его с помощью this.javaClass.getResourceAsStream
. Должен ли он быть создан в папке build/resources
? Он всегда возвращает null
, а load
вылетает с NullPointerException
Ой! Все заработало! Просто нужно добавить /
перед version.properties
в функции getResourceAsStream
! Спасибо!!!
Отлично, я собирался это предложить - исправлю свой ответ
@JKLy, К сожалению, я тоже не могу его загрузить с помощью this.javaClass.getResourceAsStream. Моя загрузка вылетает из-за исключения NullPointerException. Это все еще работает? Может мне нужно как-то запустить эту задачу "generateVersionProperties"?
Рассмотрим простой пример загрузки Spring Котлин:
@SpringBootApplication
@RestController
class DemoApplication {
@Value("\${version}")
private lateinit var version: String
@GetMapping("/version")
fun version() = version
}
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
Поскольку свойство может быть взято из application.properties, нам нужно сгенерировать этот файл с требуемой версией. Для этого мы могли бы создать файл свойств шаблона со следующим содержимым:
version=###appVersion
Теперь давайте скажем Gradle скопировать этот шаблон в папку resource
и поместить версию вместо заполнителя.
import org.apache.tools.ant.filters.ReplaceTokens
task preprocessProperties(type: Copy) {
from 'src/main/resources/templates'
into 'src/main/resources'
include 'template.properties'
rename 'template.properties', 'application.properties'
filter(ReplaceTokens, beginToken: '###', endToken: '', tokens: [appVersion: '1.0.0'])
}
compileKotlin.dependsOn preprocessProperties
И, вуаля, каждый раз, когда вы компилируете исходники Котлин, вы будете получать файл свойств с нужной вам версией.
Вы используете
gradle run
или запускаете получившуюся банку?