I have tried to use AspectJ to weave in aspects around Kotlin functions, but with no success. Maybe I'm just configuring something incorrectly, or maybe AspectJ does not support this.
Does anyone know if this is possible using e.g maven and Eclipse (or IntelliJ)? Or care to explain why it is not possible?
In addition to the other comments/answers I think it is worth pointing out that you can "weave" code before/after/around function code by using inline functions. e.g.:
fun main(vararg args: String) = nanoTimeAppendedTo(System.out, name = "main") {
/* do something, e.g.: */
Thread.sleep(0)
}
inline fun nanoTimeAppendedTo(appendable: Appendable, name: String, block: () -> Unit) {
val nanoTime = measureNanoTime(block)
appendable.appendln("`$name` took $nanoTime ns")
}
You won't have access to all of the information that AspectJ gives you but for simple cases where you simply want to reuse executing some code before/after/around some other code this works just fine.
This is what I did to weave in the aspects the "binary" way, after that the Java and Kotlin code has been compiled.
I couldn't get the aspectj-maven-plugin
to weave the aspect the "binary" way correctly, so I used the plugin jcabi-maven-plugin
instead.
See http://plugin.jcabi.com/example-ajc.html
The pom that worked for me:
<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>my.group.id</groupId>
<artifactId>my.artifact.id</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<complianceLevel>1.6</complianceLevel>
</properties>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<version>3.3</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>1.0.3</version>
<configuration>
<sourceDirs>
<sourceDir>src/main/kotlin</sourceDir>
<sourceDir>src/test/kotlin</sourceDir>
</sourceDirs>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14.1</version>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<configuration>
<mainClass>my.package.MyMainClassKt</mainClass>
</configuration>
</plugin>
</plugins>
</build>
So this works with the aspects and a few annotations defined in Java, and then using these annotations to annotate Kotlin methods and classes, to have the aspects successfully injected in the Kotlin code.
Note that if the Kotlin file has both a main method and a class defined in the same file, the Kotlin compiler produces two class files. One class with the name of the class and one class with "Kt" added to its name. Good to know if you try to use the exec-maven-plugin to run the Kotlin code.
However, this did not play very well with eclipse. Maybe IntelliJ will do a better job here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With