<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: All Things Dev</title>
    <description>The latest articles on DEV Community by All Things Dev (@all-things-dev).</description>
    <link>https://dev.to/all-things-dev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1146432%2Fb6a497a7-1faa-4968-98e0-207f26f07ac1.png</url>
      <title>DEV Community: All Things Dev</title>
      <link>https://dev.to/all-things-dev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/all-things-dev"/>
    <language>en</language>
    <item>
      <title>Simplified Hazelcast AutoConfiguration in Spring Boot</title>
      <dc:creator>All Things Dev</dc:creator>
      <pubDate>Wed, 13 Dec 2023 14:51:48 +0000</pubDate>
      <link>https://dev.to/all-things-dev/simplified-hazelcast-autoconfiguration-in-spring-boot-3oca</link>
      <guid>https://dev.to/all-things-dev/simplified-hazelcast-autoconfiguration-in-spring-boot-3oca</guid>
      <description>&lt;p&gt;Hi Everyone,&lt;br&gt;
I have been working with Hazelcast and Spring Boot for at least 6 years. In these years, probably the biggest pain was that the official Spring Boot starter for Hazelcast supported configuration only via XML file. This became cumbersome since we started supporting multiple clients with their own dedicated &lt;strong&gt;development&lt;/strong&gt;, &lt;strong&gt;test&lt;/strong&gt; and &lt;strong&gt;production&lt;/strong&gt; environments.&lt;/p&gt;

&lt;p&gt;This starter facilitates configuration of Hazelcast client / server instances through configuration properties within the application.&lt;/p&gt;

&lt;p&gt;Here is how you can simplify Hazelcast AutoConfiguration in your Spring Boot projects -&lt;/p&gt;
&lt;h2&gt;
  
  
  System Requirements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;JDK 17&lt;/li&gt;
&lt;li&gt;Spring Boot 3.x&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Add the following dependency to your &lt;code&gt;pom.xml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;dev.all-things.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;hazelcast-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0.0-M2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration Properties
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Properties
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.mode&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether to configure Hazelcast instance in 'client' or 'server' mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.cluster-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Name of the Hazelcast cluster.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.instance-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Name of the Hazelcast instance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Client Properties
&lt;/h3&gt;

&lt;p&gt;Set &lt;code&gt;application.cache.hazelcast.mode = client&lt;/code&gt; to use following properties.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.client.server-addresses&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comma-separated list of server addresses.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.client.connection-timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Timeout value for nodes to accept client connection requests.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.client.smart-routing.enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether to enable smart-routing.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Server Properties
&lt;/h3&gt;

&lt;p&gt;Set &lt;code&gt;application.cache.hazelcast.mode = server&lt;/code&gt; to use following properties.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.port&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hazelcast server port.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.primary-address&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hazelcast primary server address.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.secondary-addresses&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Alternate network addresses for server to bind to.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.port-auto-increment.enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether to enable port auto-increment.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.cluster.enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether to enable clustering mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.cluster.members&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comma-separated list of well-known cluster members.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.enabled&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Whether to enable multicast clustering mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.group-name&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Name of the multicast group.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.port&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multicast port.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.trusted-interfaces&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comma-separated list of trusted network interfaces.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.time-to-live&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Time that a node should wait for a valid multicast response.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;application.cache.hazelcast.server.multicast.timeout&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Time to live for multicast packets.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Considering the variety of practical scenarios, each comma-separated value in&lt;br&gt;
&lt;code&gt;application.cache.hazelcast.server.cluster.members&lt;/code&gt; can be specified in different format.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.20.20:5701,10.10.20.20:5702,10.10.20.20:5703&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port-range&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;10.10.20.20:[5701-5703]&lt;/code&gt; or &lt;code&gt;10.10.20.20:[5701-5702;5703;5709-5712]&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Combined&lt;/td&gt;
&lt;td&gt;&lt;code&gt;10.10.10.20:5701,10.10.20.20:[5701-5702;5703;5709-5712]&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Standalone Server Configuration
&lt;/h3&gt;

&lt;p&gt;Minimal standalone server configuration requires following properties in your &lt;code&gt;application.properties&lt;/code&gt; file -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hazelcast properties
&lt;/span&gt;&lt;span class="py"&gt;application.cache.hazelcast.mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.cluster-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.instance-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev-node-1&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.primary-address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5701&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clustered Server Configuration
&lt;/h3&gt;

&lt;p&gt;Minimal clustered server configuration requires following properties in your &lt;code&gt;application.properties&lt;/code&gt; file -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hazelcast properties
&lt;/span&gt;&lt;span class="py"&gt;application.cache.hazelcast.mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;server&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.cluster-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.instance-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev-node-1&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.primary-address&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.port&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5701&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.cluster.enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.server.cluster.members&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1:5702&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client Configuration
&lt;/h3&gt;

&lt;p&gt;Minimal client configuration requires following properties in your &lt;code&gt;application.properties&lt;/code&gt; file -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hazelcast properties
&lt;/span&gt;&lt;span class="py"&gt;application.cache.hazelcast.mode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;client&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.cluster-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.instance-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dev-node-1&lt;/span&gt;
&lt;span class="py"&gt;application.cache.hazelcast.client.server-addresses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1:5701&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/all-things-dev/hazelcast-spring-boot-starters"&gt;GitHub Project&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep in Touch
&lt;/h2&gt;

&lt;p&gt;Please follow me on &lt;a href="https://twitter.com/all_things_dev"&gt;Twitter&lt;/a&gt; where I regularly share my experiences with useful tools and frameworks.&lt;/p&gt;

</description>
      <category>hazelcast</category>
      <category>springboot</category>
    </item>
    <item>
      <title>Spring Boot Multi-Module Project with Gradle Convention Plugin</title>
      <dc:creator>All Things Dev</dc:creator>
      <pubDate>Fri, 25 Aug 2023 20:22:11 +0000</pubDate>
      <link>https://dev.to/all-things-dev/spring-boot-multi-module-project-with-gradle-convention-plugin-mhc</link>
      <guid>https://dev.to/all-things-dev/spring-boot-multi-module-project-with-gradle-convention-plugin-mhc</guid>
      <description>&lt;p&gt;Hi Everyone,&lt;br&gt;
I have been working with Java and Maven for over a decade. Recently, I started migrating many of my projects to Kotlin and Gradle. Most of these projects are multi-module projects with single parent &lt;code&gt;pom.xml&lt;/code&gt; for dependency management.&lt;/p&gt;

&lt;p&gt;During my research I learned that Gradle provides similar organization of modules with convention plugin. However, there seems to be no direct guide or reference to create a working Spring Boot multi-module project with Gradle convention plugin configuration. The references that I found were pretty useful in demonstrating the core concepts but nothing which could be directly applicable to our use case. This is the reason I decided to write this article.&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;PROJECT-ROOT&amp;gt;
|   settings.gradle.kts
|                       
+---buildSrc
|   |   build.gradle.kts
|   |   settings.gradle.kts
|   \---src
|       \---main
|           \---kotlin
|                   dev.all_things.reference.spring-boot-parent.gradle.kts
|                   
\---web-app
    |   build.gradle.kts
    |   
    \---src
        \---main
            +---kotlin
            |   \---config
            |           Application.kt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Convention Plugin Configuration
&lt;/h2&gt;

&lt;p&gt;It refers to a build configuration file which defines set of plugins, dependencies and compiler settings. Each file is a Gradle script with &lt;code&gt;gradle.kts&lt;/code&gt; extension. Gradle will expose each configuration as a plugin with file name as identity e.g. &lt;code&gt;dev.all_things.reference.spring-boot-parent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;buildSrc&lt;/code&gt; is a special directory where all convention plugin configurations reside. This directory is nothing but a standalone Gradle project with its own independent dependency and repository configuration.&lt;/p&gt;

&lt;p&gt;Like any standard Gradle project &lt;code&gt;buildSrc/settings.gradle.kts&lt;/code&gt; specifies repositories required for downloading plugings and dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Global plugin management&lt;/span&gt;
&lt;span class="nf"&gt;pluginManagement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Project level repositories for plugins&lt;/span&gt;
    &lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Google mirror of Maven Central for optimized performance&lt;/span&gt;
        &lt;span class="nf"&gt;google&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Maven Central (primary) plugin repository&lt;/span&gt;
        &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Gradle plugin repository&lt;/span&gt;
        &lt;span class="nf"&gt;gradlePluginPortal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Global dependency management&lt;/span&gt;
&lt;span class="nf"&gt;dependencyResolutionManagement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Project level repositories for dependencies.
     *
     * Gradle uses its own repository by default.
     * Maven repository needs to be explicitly configured.
     */&lt;/span&gt;
    &lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// Google mirror of Maven Central for optimized performance&lt;/span&gt;
        &lt;span class="nf"&gt;google&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;// Maven Central (primary) artifact repository&lt;/span&gt;
        &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;buildSrc/build.gradle.kts&lt;/code&gt; specifies common dependencies (and corresponding versions) required by the sub-modules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"kotlin-application-parent"&lt;/span&gt;

&lt;span class="c1"&gt;// Convention plugin configuration&lt;/span&gt;
&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Enables convention definitions in src/main/kotlin&lt;/span&gt;
    &lt;span class="n"&gt;`kotlin-dsl`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// 'buildSrc' specific dependencies&lt;/span&gt;
&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Kotlin&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.10"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.jetbrains.kotlin:kotlin-allopen:1.9.10"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Spring Boot&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.boot:spring-boot-gradle-plugin:3.1.3"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;kotlin-dsl&lt;/code&gt; is configured as a plugin. This enables Kotlin DSL for creating reusable build configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Convention plugin configuration&lt;/span&gt;
&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Enables convention definitions in src/main/kotlin&lt;/span&gt;
    &lt;span class="n"&gt;`kotlin-dsl`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dev.all_things.reference.spring-boot-parent.gradle.kts&lt;/code&gt; specifies the actual build configuration that sub-modules can reuse. This file supports all configurations as a standard &lt;code&gt;build.gradle.kts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Plugins common for sub-modules&lt;/span&gt;
&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Spring Boot plugin configuration&lt;/span&gt;
    &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org.springframework.boot"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Spring Boot dependency management configuration&lt;/span&gt;
    &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.spring.dependency-management"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Kotlin compiler plugin for JVM&lt;/span&gt;
    &lt;span class="nf"&gt;kotlin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jvm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Kotlin plugin for Spring&lt;/span&gt;
    &lt;span class="nf"&gt;kotlin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"plugin.spring"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dev.all_things.reference"&lt;/span&gt;
&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0.0-SNAPSHOT"&lt;/span&gt;

&lt;span class="c1"&gt;// Enabled by 'Kotlin' plugin&lt;/span&gt;
&lt;span class="nf"&gt;kotlin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// JDK specific toolchain configuration&lt;/span&gt;
    &lt;span class="nf"&gt;jvmToolchain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Dependencies common for sub-modules&lt;/span&gt;
&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// ..&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Module Configuration
&lt;/h2&gt;

&lt;p&gt;Now that convention configuration is ready, it can be imported by sub-modules using generated plugin id i.e. &lt;code&gt;dev.all_things.reference.spring-boot-parent&lt;/code&gt; in their &lt;code&gt;build.gradle.kts&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Other module specific plugins&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="c1"&gt;// Spring Boot parent configuration for dependency management&lt;/span&gt;
    &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"dev.all_things.reference.spring-boot-parent"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;A project can have multiple convention configurations. Multiple sub-modules in a project can also import one or more such configurations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/all-things-dev/kotlin-application-template"&gt;GitHub Project&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep in Touch
&lt;/h2&gt;

&lt;p&gt;Please follow me on &lt;a href="https://twitter.com/all_things_dev"&gt;Twitter&lt;/a&gt; where I regularly share my experiences with useful tools and frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=So0j4RnoKkU"&gt;https://www.youtube.com/watch?v=So0j4RnoKkU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=iu_Tftpm6L8"&gt;https://www.youtube.com/watch?v=iu_Tftpm6L8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=1hjle_eqEsw"&gt;https://www.youtube.com/watch?v=1hjle_eqEsw&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>springboot</category>
      <category>gradle</category>
      <category>kotlin</category>
    </item>
  </channel>
</rss>
