Kotlin in your AEM project

July 25, 2017    aem kotlin maven tutorial


Below is a step-by-step guide on how to add kotlin to a maven based AEM project. (referenced project could be find here)

Prerequisites

  1. Maven installed on your machine(you can download it here)
  2. Your favourite IDE (I prefer Intellij (download here) Community will be enough for us, but you can try ultimate version)
  3. Java 8
  4. AEM instance 6.0 +

1. Create a maven project

aem archetype

  • Choose a version for which one you want to create a project, I will use version 11
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate \
 -DarchetypeGroupId=com.adobe.granite.archetypes \
 -DarchetypeArtifactId=aem-project-archetype \
 -DarchetypeVersion=11 \
 -DarchetypeCatalog=https://repo.adobe.com/nexus/content/groups/public/

building from archetype

You will have to insert some properties during creation:

define params

2. Add kotlin to the newly created project

Open project with your favourite IDE (here I will use Intellij)

open newly created project

You need to wait a bit… after that you need to have the following structure:

project structure

Add kotlin properties

Find the main pom.xml file and add kotlin version into the “Properties” section

<kotlin.version>1.1.2-5</kotlin.version>

Add kotlin dependencies

  • Add kotlin OSGI dependency. Find the <dependencyManagement> section in the main pom file and add this dependency
            <dependency>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-osgi-bundle</artifactId>
                <version>${kotlin.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>*</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
  • Add Java 8 kotlin-lib
            <dependency>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-stdlib-jre8</artifactId>
                <version>${kotlin.version}</version>
            </dependency>

Change compiler settings

Find <build> section in the main pom file, then find <!– Maven Compiler Plugin –>

Replace this :

            <!-- Maven Compiler Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

With this:

            <!--Kotlin compiler plugin-->
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals> <goal>compile</goal> </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
                                <sourceDir>${project.basedir}/src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <goals> <goal>test-compile</goal> </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
                                <sourceDir>${project.basedir}/src/test/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <!-- Maven Compiler Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
                <executions>
                    <!-- Replacing default-compile as it is treated specially by maven -->
                    <execution>
                        <id>default-compile</id>
                        <phase>none</phase>
                    </execution>
                    <!-- Replacing default-testCompile as it is treated specially by maven -->
                    <execution>
                        <id>default-testCompile</id>
                        <phase>none</phase>
                    </execution>
                    <execution>
                        <id>java-compile</id>
                        <phase>compile</phase>
                        <goals> <goal>compile</goal> </goals>
                    </execution>
                    <execution>
                        <id>java-test-compile</id>
                        <phase>test-compile</phase>
                        <goals> <goal>testCompile</goal> </goals>
                    </execution>
                </executions>
            </plugin>

Above we have replaced the default compiler in order to use kotlin instead. Now we have a kotlin compiler to compile java and kotlin sources.

Embed the kotlin OSGI bundle.

Earlier we added the kotlin OSGI dependency. Now we need it to be deployed with our project, so we need to find the pom.xml of the ui.app module.

ui app module

  • First of all, add the dependency
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-osgi-bundle</artifactId>
        </dependency>
  • Now we need to embed it. Find
            <!-- ====================================================================== -->
            <!-- V A U L T   P A C K A G E   P L U G I N                                -->
            <!-- ====================================================================== -->

in this pom and add the following code in the <embeddeds> section:

                        <embedded>
                            <groupId>org.jetbrains.kotlin</groupId>
                            <artifactId>kotlin-osgi-bundle</artifactId>
                            <target>/apps/aem-ktln/install</target>
                        </embedded>

Great! After that when we deploy our project, the kotlin OSGI bundle will also be available on the environment.

Let’s move forward.

Add kotlin servlet

Before we create our first kotlin servlet, we need to add the dependency to the ‘core’ bundle, therefore we need to find the pom file for the ‘core’ bundle.

core bundle pom location

  • Add the dependency
        <!--Kotlin dependency-->
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jre8</artifactId>
        </dependency>
  • Add a kotlin source folder

kotlin source folder

Fantastic! Now we are finally ready to write the first servlet in kotlin

  • Create a kotlin Class

kotlin class

  • Add the following code in the file you just created
@Component(service = arrayOf(Servlet::class),
        property = arrayOf(Constants.SERVICE_DESCRIPTION + "=Simple Kotlin Demo Servlet",
                "sling.servlet.methods=" + HttpConstants.METHOD_GET,
                "sling.servlet.paths=" + "/services/kotlin/demo/servlet"))
class SimpleKotlinServlet : SlingAllMethodsServlet() {

    override fun doGet(request: SlingHttpServletRequest, response: SlingHttpServletResponse) {
        val jsonResponse = JSONObject().put("name", "kotlin servlet")
                .put("version", "1.1.2-5").toString()
        response.writer.write(jsonResponse)
    }
}
  • Deploy the application to your AEM instance
mvn clean install -PautoInstallPackage

We registered servlet on the path ‘/services/kotlin/demo/servlet’, so following successful deployment you can go to http://localhost:4502/services/kotlin/demo/servlet and verify that it works. You should now see the following picture:

servlet in action

P.S. all code can be found at this repo. If you have any questions, suggestions, remarks, feel free to leave those in the “Comments” section.




comments powered by Disqus