Alex
Alex Coding pays my food bills

Creating a self-service project generator with a custom Spring Initializr


Creating a self-service project generator with a custom Spring Initializr

start.spring.io is the staple of all new Spring Boot projects, providing the ability to quickly add dependencies and spring starters with just a click of a button. But what would you do if you needed to add a dependency that isn’t available from start.spring.io? Normally you would have to download the Spring project from start.spring.io and add the dependency manually to the project. This presents some significant downsides for an enterprise wishing to standardise version dependencies across its microservices. Today we are going to look at an alternative way to help standardise a project’s dependencies by extending start.spring.io to generate 3rd party dependencies not found on the start.spring.io site.

Spring Initializr, the project which powers start.spring.io, can be summed up from the Spring Initializr documentation

Spring Initializr provides an extensible API to generate JVM-based projects, and to inspect the metadata used to generate projects, for instance to list the available dependencies and versions.

The guys at Pivotal were kind enough to put the source code for Spring Initializr and start.spring.io on Github, which we will be cloning and using here. Once you have cloned start.spring.io you will notice the project consists of three modules:

  • start-client: Contains ReactJS components for the UI
  • start-site: Java module containing Spring Initializr components
  • start-site-verification: Contains verification tests

Adding a new dependency

In this blog post we will be focussing on the start-site module to add additional dependencies. Spring Initializr uses the application.yaml to configure Initializr’s output. Opening up the application.yaml you can see the relevant information under the initializr property. We are going to extend start.spring.io to allow a user to add CRNK dependencies to the project. If you haven’t used CRNK before I recommend investigating it as a means of standing up basic microservices in a JSON Api compliant way. The CRNK project doesn’t publish the latest releases to Maven Central, instead it publishes to JCenter meaning we will have to add a custom repository. It also provides a Bill of Materials (BoM) to help manage versioning. We will be using these facets to demonstrate some of the features of Spring Initializr.

Looking under initializr in the application.yaml file already defined for start.spring.io, you can see that it is split up into two main sections:

  • env - this contains environment specific options, for example here we can add definitions for BoM, custom remote repositories or specific configurations for build tools
  • dependencies - a list of all dependencies that the api will provide

We will be using the env property to add the JCenter repository and the CRNK BoM. Firstly, let’s add the JCenter repository. Under the initializr.env.repositories property add the JCenter repository like so:

1
2
3
4
5
6
initializr:
    env:
      jcenter:
        name: jcenter
        url: https://jcenter.bintray.com/
        snapshotsEnabled: false

Next add the BoM under initializr.env.boms. The latest versions for the CRNK BoM can be found at JCenter. The repository name needs to match the name of the repository defined in the repositories sections, in this case jcenter.

1
2
3
4
5
6
7
8
initializr:
  env:
    boms:
      crnk:
        groupId: io.crnk
        artifactId: crnk-bom
        version: 3.1.20191113192440
        repository: jcenter

And finally for this to be useful we need to define a dependency that we can select in our extended start.spring.io website

1
2
3
4
5
6
7
8
9
10
11
12
  initializr:
    dependencies:
        - name: CRNK
        content:
            - name: Crnk Spring Boot 2
            id: crnk-spring-boot-2
            description: Providers a JSON API implementation for Spring Boot.
            groupId: io.crnk
            artifactId: crnk-setup-spring-boot2
            starter: false
            bom: crnk
            repository: jcenter

Similar dependencies can be grouped together under the content tab. For example, we could have added another dependency for the CRNK JPA module which would generate another dependency in the website but grouped under the CRNK section. The bom fields tell initializr to add the BoM for CRNK if this dependency is selected. Likewise initializr will add the JCenter repository if the dependency is selected. The starter field needs to be set to false to prevent initializr from removing other selected dependencies.

An example of the above code changes can be found in this commit. Now the configuration has been sorted it’s time to run the project locally to see the results. In the root of the project, run the maven command:

1
./mvnw clean spring-boot:run -pl start-site

Navigate to http://localhost:8080 to check out the updated UI. In the dependency search bar type CRNK and the Crnk Spring Boot dependency should now be visible.

Crnky

Selecting the CRNK spring boot dependency and clicking the explore button at the bottom of the page shows what the generated project will look like. You should be able to see the CRNK dependency and JCenter in the pom.xml (or build.gradle if you have selected gradle as your build tool). Clicking generate will download the project as a zip file for you.

Updating Intellij to use your Initializr

Intellij Ultimate can talk directly to the Initializr api and import the project all within the Intellij UI. To create a project using the custom Initializr website we have created go to New Project -> Spring Initializr in Intellij and change the Initializr service url to http://localhost:8080

Intellij Spring Initializr

Go through the normal Intellij Spring setup until the dependency selection page appears. Here you should be able to see CRNK as an optional dependency to add

Intellij Crnk

Conclusion

We have looked at extending the start.spring.io website to generate projects using custom dependencies, repositories and Bill of Materials, all with simple additions to the application.yaml file. The Spring Initializr project is very customizable, in a future post we will be looking at generating custom code based on dependency selection.

comments powered by Disqus