Получить версию в коде Kotlin / Java в проекте Gradle

У меня есть веб-сервис, закодированный на 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 run или запускаете получившуюся банку?

pixix4 01.05.2018 16:13

Почему бы вам просто не написать версию прямо в исходный код через gradle, используя filter(ReplaceTokens...)?

xuesheng 02.05.2018 14:54

@xuesheng Никогда не слышал об этом методе. Не стесняйтесь добавлять возможный ответ ниже.

Jean-François Côté 03.05.2018 15:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
3
4 250
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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 в вашем коде вместо использования файла свойств.

Спасибо за ответ. Я попробую это!

Jean-François Côté 01.05.2018 19:17

Первый раздел работает отлично, файл создается в папке сборки. К сожалению, я не могу загрузить его с помощью this.javaClass.getResourceAsStream. Должен ли он быть создан в папке build/resources? Он всегда возвращает null, а load вылетает с NullPointerException

Jean-François Côté 01.05.2018 20:17

Ой! Все заработало! Просто нужно добавить / перед version.properties в функции getResourceAsStream! Спасибо!!!

Jean-François Côté 01.05.2018 20:20

Отлично, я собирался это предложить - исправлю свой ответ

JK Ly 01.05.2018 20:21

@JKLy, К сожалению, я тоже не могу его загрузить с помощью this.javaClass.getResourceAsStream. Моя загрузка вылетает из-за исключения NullPointerException. Это все еще работает? Может мне нужно как-то запустить эту задачу "generateVersionProperties"?

Dmitriy Greh 09.10.2018 15:22

Рассмотрим простой пример загрузки 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

И, вуаля, каждый раз, когда вы компилируете исходники Котлин, вы будете получать файл свойств с нужной вам версией.

Другие вопросы по теме