Compiler Plugins

    For instance, when you use Spring, you don’t need all the classes to be open, but only classes annotated with specific annotations like @Configuration or @Service. All-open allows to specify such annotations.

    We provide all-open plugin support both for Gradle and Maven with the complete IDE integration.

    Note: For Spring you can use the kotlin-spring compiler plugin (see below).

    Add the plugin artifact to the buildscript dependencies and apply the plugin:

    As an alternative, you can enable it using the plugins block:

    1. plugins {
    2. id "org.jetbrains.kotlin.plugin.allopen" version "1.4.21"
    3. }

    Then specify the list of annotations that will make classes open:

    1. allOpen {
    2. annotation("com.my.Annotation")
    3. // annotations("com.another.Annotation", "com.third.Annotation")
    4. }

    If the class (or any of its superclasses) is annotated with com.my.Annotation, the class itself and all its members will become open.

    It also works with meta-annotations:

    1. @com.my.Annotation
    2. annotation class MyFrameworkAnnotation
    3. @MyFrameworkAnnotation
    4. class MyClass // will be all-open

    MyFrameworkAnnotation is annotated with the all-open meta-annotation com.my.Annotation, so it becomes an all-open annotation as well.

    Using in Maven

    Here’s how to use all-open with Maven:

    1. <plugin>
    2. <artifactId>kotlin-maven-plugin</artifactId>
    3. <groupId>org.jetbrains.kotlin</groupId>
    4. <version>${kotlin.version}</version>
    5. <configuration>
    6. <compilerPlugins>
    7. <!-- Or "spring" for the Spring support -->
    8. <plugin>all-open</plugin>
    9. </compilerPlugins>
    10. <pluginOptions>
    11. <!-- Each annotation is placed on its own line -->
    12. <option>all-open:annotation=com.my.Annotation</option>
    13. <option>all-open:annotation=com.their.AnotherAnnotation</option>
    14. </pluginOptions>
    15. </configuration>
    16. <dependencies>
    17. <dependency>
    18. <groupId>org.jetbrains.kotlin</groupId>
    19. <artifactId>kotlin-maven-allopen</artifactId>
    20. <version>${kotlin.version}</version>
    21. </dependency>
    22. </dependencies>
    23. </plugin>

    Please refer to the “Using in Gradle” section above for the detailed information about how all-open annotations work.

    Spring support

    If you use Spring, you can enable the kotlin-spring compiler plugin instead of specifying Spring annotations manually. The kotlin-spring is a wrapper on top of all-open, and it behaves exactly the same way.

    1. buildscript {
    2. dependencies {
    3. classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    4. }
    5. }
    6. apply plugin: "kotlin-spring" // instead of "kotlin-allopen"

    Or using the Gradle plugins DSL:

    1. plugins {
    2. id "org.jetbrains.kotlin.plugin.spring" version "1.4.21"
    3. }

    In Maven, the spring plugin is provided by the kotlin-maven-allopen plugin dependency, so to enable it:

    1. <configuration>
    2. <compilerPlugins>
    3. <plugin>spring</plugin>
    4. </compilerPlugins>
    5. </configuration>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.jetbrains.kotlin</groupId>
    9. <version>${kotlin.version}</version>
    10. </dependency>
    11. </dependencies>

    The plugin specifies the following annotations: , @Async, , @Cacheable and . Thanks to meta-annotations support classes annotated with @Configuration, , @RestController, or @Repository are automatically opened since these annotations are meta-annotated with .

    Of course, you can use both kotlin-allopen and kotlin-spring in the same project.

    Note that if you use the project template generated by the start.spring.io service, the kotlin-spring plugin will be enabled by default.

    All-open compiler plugin JAR is available in the binary distribution of the Kotlin compiler. You can attach the plugin by providing the path to its JAR file using the Xplugin kotlinc option:

    You can specify all-open annotations directly, using the annotation plugin option, or enable the “preset”. The only preset available now for all-open is spring.

    1. # The plugin option format is: "-P plugin:<plugin id>:<key>=<value>".
    2. # Options can be repeated.
    3. -P plugin:org.jetbrains.kotlin.allopen:annotation=com.my.Annotation
    4. -P plugin:org.jetbrains.kotlin.allopen:preset=spring

    The no-arg compiler plugin generates an additional zero-argument constructor for classes with a specific annotation.

    The generated constructor is synthetic so it can’t be directly called from Java or Kotlin, but it can be called using reflection.

    This allows the Java Persistence API (JPA) to instantiate a class although it doesn’t have the zero-parameter constructor from Kotlin or Java point of view (see the description of kotlin-jpa plugin ).

    Using in Gradle

    The usage is pretty similar to all-open.

    Add the plugin and specify the list of annotations that must lead to generating a no-arg constructor for the annotated classes.

    1. buildscript {
    2. dependencies {
    3. classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    4. }
    5. }
    6. apply plugin: "kotlin-noarg"
    1. plugins {
    2. id "org.jetbrains.kotlin.plugin.noarg" version "1.4.21"
    3. }

    Then specify the list of no-arg annotations:

    1. noArg {
    2. annotation("com.my.Annotation")
    3. }

    Enable invokeInitializers option if you want the plugin to run the initialization logic from the synthetic constructor. Starting from Kotlin 1.1.3-2, it is disabled by default because of and KT-18668 which will be addressed in the future.

    1. noArg {
    2. invokeInitializers = true
    3. }

    Using in Maven

    1. <plugin>
    2. <artifactId>kotlin-maven-plugin</artifactId>
    3. <groupId>org.jetbrains.kotlin</groupId>
    4. <version>${kotlin.version}</version>
    5. <configuration>
    6. <compilerPlugins>
    7. <!-- Or "jpa" for JPA support -->
    8. <plugin>no-arg</plugin>
    9. </compilerPlugins>
    10. <pluginOptions>
    11. <option>no-arg:annotation=com.my.Annotation</option>
    12. <!-- Call instance initializers in the synthetic constructor -->
    13. <!-- <option>no-arg:invokeInitializers=true</option> -->
    14. </pluginOptions>
    15. </configuration>
    16. <dependencies>
    17. <dependency>
    18. <groupId>org.jetbrains.kotlin</groupId>
    19. <artifactId>kotlin-maven-noarg</artifactId>
    20. <version>${kotlin.version}</version>
    21. </dependency>

    As with the kotlin-spring plugin wrapped on top of all-open, kotlin-jpa is wrapped on top of no-arg. The plugin specifies @Entity, and @MappedSuperclass no-arg annotations automatically.

    That’s how you add the plugin in Gradle:

    1. buildscript {
    2. dependencies {
    3. classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
    4. }
    5. }
    6. apply plugin: "kotlin-jpa"

    Or using the Gradle plugins DSL:

    In Maven, enable the jpa plugin:

    1. <compilerPlugins>
    2. <plugin>jpa</plugin>
    3. </compilerPlugins>

    Using in CLI

    As with all-open, add the plugin JAR file to the compiler plugin classpath and specify annotations or presets:

    1. -Xplugin=$KOTLIN_HOME/lib/noarg-compiler-plugin.jar
    2. -P plugin:org.jetbrains.kotlin.noarg:annotation=com.my.Annotation
    3. -P plugin:org.jetbrains.kotlin.noarg:preset=jpa

    The sam-with-receiver compiler plugin makes the first parameter of the annotated Java “single abstract method” (SAM) interface method a receiver in Kotlin. This conversion only works when the SAM interface is passed as a Kotlin lambda, both for SAM adapters and SAM constructors (see the documentation for more details).

    Here is an example:

    1. public @interface SamWithReceiver {}
    2. @SamWithReceiver
    3. public interface TaskRunner {
    4. void run(Task task);
    5. }
    1. fun test(context: TaskContext) {
    2. val runner = TaskRunner {
    3. // Here 'this' is an instance of 'Task'
    4. println("$name is started")
    5. context.executeTask(this)
    6. println("$name is finished")
    7. }
    8. }

    Using in Gradle

    The usage is the same to all-open and no-arg, except the fact that sam-with-receiver does not have any built-in presets, and you need to specify your own list of special-treated annotations.

    1. buildscript {
    2. dependencies {
    3. classpath "org.jetbrains.kotlin:kotlin-sam-with-receiver:$kotlin_version"
    4. }
    5. }
    6. apply plugin: "kotlin-sam-with-receiver"

    Then specify the list of SAM-with-receiver annotations:

    1. samWithReceiver {
    2. annotation("com.my.SamWithReceiver")
    3. }
    1. <plugin>
    2. <artifactId>kotlin-maven-plugin</artifactId>
    3. <groupId>org.jetbrains.kotlin</groupId>
    4. <version>${kotlin.version}</version>
    5. <configuration>
    6. <compilerPlugins>
    7. <plugin>sam-with-receiver</plugin>
    8. </compilerPlugins>
    9. <pluginOptions>
    10. <option>
    11. sam-with-receiver:annotation=com.my.SamWithReceiver
    12. </option>
    13. </pluginOptions>
    14. </configuration>
    15. <dependencies>
    16. <dependency>
    17. <groupId>org.jetbrains.kotlin</groupId>
    18. <artifactId>kotlin-maven-sam-with-receiver</artifactId>
    19. <version>${kotlin.version}</version>
    20. </dependency>
    21. </plugin>

    Using in CLI

    Just add the plugin JAR file to the compiler plugin classpath and specify the list of sam-with-receiver annotations: