All articles
Contents

    Development in an Isolated Environment - How to Manage Dependencies?

            artifactId toUpload.artifactId
            groupId toUpload.groupId
            version toUpload.version
            descriptors.each { descriptor ->
                artifact(descriptor.filePath) {
                    classifier descriptor.classifier.type
                    extension descriptor.classifier.extenstion
                }
            }
        }
    }
    

    }

    Thanks to Gradle we avoid the collisions while resolving transitive dependencies and significantly speed up the application operation.

    Project Build

    For building CUBA SDK we used the same approach as for CUBA CLI. With the jlink tool we built all the necessary modules to bundle them with a custom JRE delivered together with the application. This approach made SDK independent from the installed Java version. You can find an example of such a build in the CLI Core Sample project.

    Third-party Plugins Support

    Since CUBA SDK is based on the CLI Core library, it supports third-party plugins. At the moment, SDK has maven and gradle components dependency managers and providers for CUBA components implemented via third-party plugins.

    Let’s have a look at the example of how we can extend the SDK functionality with a plugin. We’ll create a provider for Spring Boot starters from the widely known Spring Initializr.

    First let’s create a new project. As an example we’ll use the CUBA CLI plugin, as it’s described here, and add the dependencies:

    implementation "com.haulmont.cli.core:cli-core:1.0.0"
    implementation "com.haulmont.cli.sdk:cuba-sdk:1.0.1"
    

    Create a new provider for spring boot starters - SpringBootProvider, which extends BintraySearchComponentProvider. BintraySearchComponentProvider enables automatic search of accessible component versions using the Bintray API.

    class SpringBootProvider : BintraySearchComponentProvider() {
       var springComponentsInfo: SpringComponentsInfo? = null
    

    override fun getType() = "boot-starter"
    override fun getName() = "Spring boot starter"

    ...

    override fun load() {
    springComponentsInfo = Gson().fromJson(readSpringFile(), SpringComponentsInfo::class.java)
    }

    private fun readSpringFile(): String {
    return SpringComponentsPlugin::class.java.getResourceAsStream("spring-components.json")
    .bufferedReader()
    .use { it.readText() }
    }

    This provider will search for the accessible components from spring-components.json file which is the json version of yml file in Spring Initializr application.

    For mapping from json to objects let’s create simple data classes:

    data class SpringComponent(
       val name: String,
       val id: String,
       val groupId: String?,
       val artifactId: String?,
       val description: String?,
       val starter: Boolean? = true
    )
    

    data class SpringComponentCategory(
    val name: String,
    val content: List<SpringComponent>
    )

    data class SpringInitializr(
    val dependencies: List<SpringComponentCategory>
    )

    data class SpringComponentsInfo(
    val initializr: SpringInitializr
    )

    To add this provider to other SDK providers we need to register the provider in the init event of the plugin:

    class SpringBootComponentsPlugin : CliPlugin {
       private val componentRegistry: ComponentRegistry by sdkKodein.instance<ComponentRegistry>()
    

    @Subscribe
    fun onInit(event: InitPluginEvent) {
    val bootProvider = SpringBootProvider()
    componentRegistry.addProviders(bootProvider)
    bootProvider.load()
    }

    }

    Jmix is an open-source platform for building enterprise applications in Java