Gradle Goodness: Validate Model In Rule Based Model Configuration

Rule based model configuration gives Gradle more knowledge about the objects and their dependencies. This information can be used by Gradle to optimise the build process. We define rules on how we want Gradle to create objects and how we want to mutate objects in a class that extends RuleSource. We can also add rules to validate objects available in the Gradle model space. We use the @Validate annotation on methods that have validation logic. The first argument of the method is of the type of the object we want to validate. This type must be managed by Gradle.

Continue reading

Gradle Goodness: Replacing << Operator For Tasks

Gradle 3.2 deprecates the << operator to add actions to a task. The << operator maps to the leftShift method of a task. This operator confuses a lot people that are new to Gradle. Because without the operator we are configuring a task instead of adding actions. I can tell from experience the mistake is easily made. If we use the << in our build script with Gradle 3.2 we get a warning on the console. The warning message already mentions a solution: use the doLast method to add actions.

Continue reading

Gradle Goodness: Set Default Values With Rule Based Model Configuration

When we use Rule based model configuration in our Gradle project we can give Gradle rules on how to manage objects from the model space. These rules are defined in a class that extends RuleSource. When we want to set some default values for properties of a model object (in Gradle terms this is a subject) we can use the @Defaults annotation. Rules annotated with @Defaults are invoked right after the object is created and before any other methods that can mutate the state of the object.

The method, to set the default values, must have the type of the object as first parameter. Other parameters are considered input parameters and can be used to set a default value based on other model objects.

Continue reading

Gradle Goodness: Show Hidden Model Objects

We use the model task to see which objects are available in the Gradle model space. The model spaced is managed by Rule based model configuration. Objects can be defined as hidden by the object author(s). By default a hidden object is not shown in the model report. We must use the task option --showHidden to show also the hidden objects in the model report.

Continue reading

Gradle Goodness: Get Model Report In Short Format

The Gradle model task shows the objects in the model space of Gradle. The output shows the object hierarchy. By default a full report is shown, with a lot of information. We can customize the output format with the --format task argument. The default value is full, but we can also use the value short. With the value short a lot less information is shown.

Continue reading

Gradle Goodness: Adding Task With Rule Based Model Configuration

Gradle has an incubating feature Rule based model configuration. This is a new way to configure Gradle projects where Gradle has more control of the configuration and the dependencies between configuration objects. This allows Gradle to resolve configuration values before they are used, because Gradle knows there is a dependency. With this new model we don’t need any lazy evaluation “tricks” we had to use. For example there was an internal convention mapping mechanism for tasks to assign values to a task configuration after the task was already created. Also the project.afterEvalute is a mechanism to have late binding for task properties. With the new rule based model Gradle can do without these options, we can rely on Gradle resolving all dependent configuration values when we create a task.

Continue reading

Gradle Goodness: Custom Plugin Repositories With Plugins DSL

To apply a plugin in our Gradle build script we can use the plugins DSL. The plugins DSL is very concise and allows Gradle to be more efficient and more in control when loading the plugin. Normally the plugin we define is fetched from the Gradle plugin portal. If we have our own repository, for example on the intranet of our company, we have to define that extra repository with a pluginRepositories configuration block in the settings.gradle file of our project.

Continue reading

Gradle Goodness: Specify Wrapper Version and Distribution Type From Command Line

Gradle has the built-in task wrapper to create a Gradle wrapper. The Gradle wrapper can be part of our project so other people can build our project with Gradle, without the need for them to install Gradle. Also if we specify the Gradle wrapper we can make sure the correct Gradle version is used. To specify the version we must use the option --gradle-version. This version can be different than the Gradle version we use to create the Gradle wrapper. Since Gradle 3.1 we can also specify the distribution type of the Gradle wrapper. We choose between a binary distribution or the all distribution, which contains documentation and source code. Especially IDEs like to have the all distribution type, so they can provide better help in their editors.

With the following wrapper command we create a wrapper for Gradle 3.1 and the all distribution type. For a binary distribution we either use the value bin or we don’t specify the option, so Gradle falls back to the default value bin.

We can check the file gradle/wrapper/gradle-wrapper.properties and look for the key distributionUrl. We see the value points to the correct Gradle version and distribution type:

Written with Gradle 3.1

Original blog post

Integrate Angular in Spring Boot with Gradle

Having a Angular HTML5 single page application and a Spring Boot application, we would like to serve the complete Angular app from Spring Boot. This blog shows you a couple simple steps to get everything up and running: run NPM from Gradle, integrate the Gradle frontend build in the main build and support HTML5 mode in the ResourceHandler of Spring Boot.

Run NPM from Gradle

Create a subdirectory called frontend with the frontend code and build scripts (webpack, npm). Let’s assume our npm start and npm run watch output to the /frontend/dist/ directory.

First we need to make sure the frontend code is build when we run gradle build on our project. We can use the plugin gradle-node-plugin for this. Go ahead and create a /frontend/build.gradle file.

Now, if we run a gradle build from our frontend subdirectory:

  • node will be downloaded
  • npm install will be executed
  • npm run build will be executed

Run integrated Gradle build

To run the frontend submodule integrated from our root project, all we need to do is include a settings.gradle at the root of the project.

Go ahead and run gradle build from the root of our project and see that npm is downloaded and the expected npm tasks are run.

We need to include the distribution of the frontend build in the JAR. Thus the frontend:build task needs to be run before we process the resources of the JAR. Go ahead and add the following snippet to /build.gradle.

Support Angular HTML5 mode

Now all we need to do is create support for HTML5 mode in Angular. Angular is a single page application and subroutes of the application are default served with a ‘#’ hashtag separator. If we want to have regular paths, we can enable HTML5 mode. The problem in serving this Angular HTML5 application from Spring Boot is that the Spring Boot ResourceHandler cannot find these resources, since the real resources is the index.html with the JavaScript files. With the next code snippet we instruct Spring Boot to look for the index.html as well. This is inspired by http://stackoverflow.com/questions/24837715/spring-boot-with-angularjs-html5mode

Happy coding!

Gradle Goodness: Change Gradle Wrapper Script Name

With the Gradle Wrapper task we can specify the name of the generated script files. By default the names are gradlew and gradlew.bat. The Wrapper task has the property scriptFile. We can set a different value for this property to let Gradle generate the script files with a different name.

In the following example we use the value mvnw (they will be surprised the build is so fast… ;-)) as the value:

Let’s run the gradleWrapper task:

Written with Gradle 3.1.

Original blog post