Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Maven configuration for using Dagger 2 in a mixed Java/Kotlin project

What is the recommended Maven setup for using Dagger 2 in a mixed Java/Kotlin project?

I found a sample project which uses Gradle: https://github.com/damianpetla/kotlin-dagger-example Something similar with Maven would be very helpful.


UPDATE: What have I tried?

I used the Kotlin configuration from kotlinlang.org/docs/reference/using-maven.html and the Dagger configuration from google.github.io/dagger. I also used the build-helper-maven-plugin plugin to integrate the annotation processing in IDEA.

My main problem was that I run into compilation cycles. My configuration mixed the compilation of Kotlin and calling the annotation processor, which generates Dagger2 classes. I unsystematically tried to separate both phases but lacked the deeper Maven understanding to get it working.

like image 680
Philipp Claßen Avatar asked Dec 06 '15 16:12

Philipp Claßen


People also ask

Can you use Maven with Kotlin?

If you still prefer to stick with good old Maven, there is no problem. There is a plugin for it to support Kotlin as well. If you don't have Maven on your machine, you can follow the instructions at https://maven.apache.org/install.html to get it installed on your local machine.

What is the use of dagger 2 in Android?

Dagger 2 is a compile-time android dependency injection framework that uses Java Specification Request 330 and Annotations. Some of the basic annotations that are used in dagger 2 are: @Module This annotation is used over the class which is used to construct objects and provide the dependencies.

What is dependency injection dagger?

The term dependency injection context is typically used to describe the set of objects which can be injected. In Dagger 2, classes annotated with @Module are responsible for providing objects which can be injected. Such classes can define methods annotated with @Provides .


1 Answers

javac can scan both source files (java) and classes in search for annotations: http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#processing

This means that you can make this work if you don't have any Dagger-generated classes referenced in Kotlin code (which means Dagger module implementations)

  1. invoke kotlin compiler (no Dagger generated types in Kotlin code)
  2. invoke annotation processor (processes annotations in both java files and kotlin-compiled files)
  3. invoke java compiler - has access to both Dagger generated types and Kotlin types

You can write your services in both java and kotlin, but the module must be created by a java class

Here is the corresponding pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.test</groupId>
    <artifactId>testkotlindagger</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <kotlin.version>1.0.6</kotlin.version>
        <dagger2.version>2.7</dagger2.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-test</artifactId>
            <version>${kotlin.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- Dagger 2 -->
        <dependency>
            <groupId>com.google.dagger</groupId>
            <artifactId>dagger</artifactId>
            <version>${dagger2.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.dagger</groupId>
            <artifactId>dagger-compiler</artifactId>
            <version>${dagger2.version}</version>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>

            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals> <goal>compile</goal> </goals>
                        <configuration>
                            <sourceDirs>
                                <source>src/main/java</source>
                                <source>src/main/kotlin</source>

                            </sourceDirs>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals> <goal>test-compile</goal> </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.bsc.maven</groupId>
                <artifactId>maven-processor-plugin</artifactId>
                <version>2.2.4</version>
                <executions>
                    <execution>
                        <id>process</id>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <phase>compile</phase>
                        <configuration>
                            <outputDirectory>target/generated-sources/annotations</outputDirectory>

                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <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>
        </plugins>
    </build>

</project>

On the other hand, if you include Dagger-generated types in your kotlin code, you must have these available before kotlin code is compiled, which means you need Kotlin-aware annotation processor (KAPT)

In this scenario the problem boils down to the question: Is kapt supported in maven?

Sadly, the answer is no, but there is a bug filed to support it: https://youtrack.jetbrains.com/issue/KT-14478

like image 172
Lesiak Avatar answered Oct 03 '22 05:10

Lesiak