4.3.1. Structure of build.gradle

This section describes the structure and main elements of the build.gradle script.

buildscript

The buildscript section of the script defines the following:

  • A version of the platform.

  • A set of repositories for loading project dependencies. See how to configure access to the repositories below.

  • Dependencies used by the build system, including the CUBA Gradle plugin.

Below the buildscript section, a few variables are defined. They are used in the script later.

cuba

The CUBA-specific build logic is encapsulated in the cuba Gradle plugin. It is included in the root of the script and in the configure section of all modules by the following statement:

apply(plugin: 'cuba')

The settings of the cuba plugin are defined in cuba section:

cuba {
    artifact {
        group = 'com.company.sales'
        version = '0.1'
        isSnapshot = true
    }
    tomcat {
        dir = "$project.rootDir/build/tomcat"
    }
    ide {
        copyright = '...'
        classComment = '...'
        vcs = 'Git'
    }
}

Let us consider the available options:

  • artifact - this section defines the group and version of the project artifacts being built. Artifact names are based on module names specified in settings.gradle.

    • group - artifact group.

    • version - artifact version.

    • isSnapshot - if true, artifact names will have the SNAPSHOT suffix.

      You can override the artifact version from the command line, for example:

      gradle assemble -Pcuba.artifact.version=1.1.1
  • tomcat - this section defines the settings of the Tomcat server which is used for fast deployment.

    • dir - location of the Tomcat installation directory.

    • port - listening port; 8080 by default.

    • debugPort - Java debug listening port; 8787 by default.

    • shutdownPort - port listening to the SHUTDOWN command; 8005 by default.

    • ajpPort - AJP connector port; 8009 by default.

  • ide - this section contains instructions for Studio and IDE.

    • vcs - a version control system for the project. Only Git and svn are currently supported.

    • copyright - copyright text to be inserted into beginning of each source file.

    • classComment - comment text to be placed above class declarations in Java source files.

  • uploadRepository - this section defines the settings of the repository where assembled project artifacts will be uploaded to upon completion of the uploadArchives task.

    • url - the repository URL. If not specified, Haulmont’s repository is used.

    • user - the repository user.

    • password - the repository password.

      You can pass the upload repository parameters from the command line with the following arguments:

      gradlew uploadArchives -PuploadUrl=http://myrepo.com/content/repositories/snapshots -PuploadUser=me -PuploadPassword=mypassword
dependencies

This section contains a set of application components used by the project. There are two types of dependencies: appComponent - for CUBA application components dependencies and uberJar - for the libraries that should be loaded before the application starts. CUBA Components are specified by their global module artifact. In the following example, three components are used: com.haulmont.cuba (cuba component of the platform), com.haulmont.reports (reports premium add-on) and com.company.base (a custom component):

dependencies {
  appComponent("com.haulmont.cuba:cuba-global:$cubaVersion")
  appComponent("com.haulmont.reports:reports-global:$cubaVersion")
  appComponent("com.company.base:base-global:0.1-SNAPSHOT")
}
configure

The configure sections contain configuration of modules. The most important part of the configuration is the declaration of dependencies. For example:

configure(coreModule) {

    dependencies {
        // standard dependencies using variables defined in the script above
        compile(globalModule)
        provided(servletApi)
        jdbc(hsql)
        testRuntime(hsql)
        // add a custom repository-based dependency
        compile('com.company.foo:foo:1.0.0')
        // add a custom file-based dependency
        compile(files("${rootProject.projectDir}/lib/my-library-0.1.jar"))
        // add all JAR files in the directory to dependencies
        compile(fileTree(dir: 'libs', include: ['*.jar']))
    }

You can add dependencies via the server configuration for core, web, and portal modules (modules that have a task with the CubaDeployment type). It makes sense in some cases. For example, for the UberJar deployment, the dependency is accessed before the application starts, and the dependency is needed for all deployment options in a specific module. Then declaring separately in the module (which is necessary, for example, for the WAR deployment) and via the uberjar configuration at the project level will cause unnecessary dependency duplication for UberJar. These dependencies will be placed in the server libs by deploy, buildWar, and buildUberJar tasks.

The entitiesEnhancing configuration block is used to configure the bytecode enhancement (weaving) of entity classes. It should be included at least in the global module, but can also be declared in each module separately.

Here, main and test are the sources sets for the projects and tests, and the optional persistenceConfig parameter enables specifying the set of persistence.xml files explicitly. If not set, the task will enhance all persistent entities listed in the *persistence.xml files located in the CLASSPATH.

configure(coreModule) {
    ...
    entitiesEnhancing {
        main {
            enabled = true
            persistenceConfig = 'custom-persistence.xml'
        }
        test {
            enabled = true
            persistenceConfig = 'test-persistence.xml'
        }
    }
}

Non-standard module dependencies can be specified in Studio in the Project properties section of CUBA project view.

In case of transitive dependencies and version conflicts, the Maven strategy of dependencies resolution will be used. According to it, the release versions have priority over the snapshot ones, and the more precise numeric qualifier is the newest. Other things being equal, the string qualifiers are prioritized in alphabetical order. For example:

1.0-beta1-SNAPSHOT         // the lowest priority
1.0-beta1
1.0-beta2-SNAPSHOT         |
1.0-rc1-SNAPSHOT           |
1.0-rc1                    |
1.0-SNAPSHOT               |
1.0                        |
1.0-sp                     V
1.0-whatever
1.0.1                      // the highest priority

Sometimes, it is necessary to use a specific version of some library, but another version of the same library gets into the project transitively from the dependency tree. For example, you may want to use the 7.2-SNAPSHOT version of CUBA platform while using an application component that is built for the platform version 7.2.0. Due to the resolution priorities explained above, the assembled project will use the platform version 7.2.0 even if you specify ext.cubaVersion = '7.2-SNAPSHOT' in the build.gradle.

To use a desired version, configure the Gradle’s resolution strategy in your build.gradle file as follows:

allprojects {
    configurations {
        all {
            resolutionStrategy.eachDependency { details ->
                if (details.requested.group == 'com.haulmont.cuba') {
                    details.useVersion '7.2-SNAPSHOT'
                }
            }
        }
    }
}

In this code block, we add a rule according to which version 7.2-SNAPSHOT will be used for all dependencies of group com.haulmont.cuba.