2016-07-02 26 views
5

Ich habe versucht, AspectJ zu verwenden, um Aspekte um Kotlin-Funktionen zu verweben, aber ohne Erfolg. Vielleicht konfiguriere ich gerade etwas falsch, oder vielleicht unterstützt AspectJ das nicht.Gibt es einen Weg in Kotlin, Code vor/nach/um Funktionen zu weben, wie es mit AspectJ in Java ist?

Weiß jemand, ob dies mit z. B. maven und Eclipse (oder IntelliJ) möglich ist? Oder erklären, warum es nicht möglich ist?

+2

Alle Instrumente auf der Bytecodeebene müssen funktionieren. Wenn dies nicht der Fall ist, benötigen wir ein minimales Beispiel für einen nicht funktionierenden Code + Build-Dateien, um festzustellen, wo das Problem liegt. – voddan

Antwort

1

Dies ist, was ich getan habe, um in den Aspekten den "binären" Weg zu weben, danach wurde der Java und Kotlin Code kompiliert.

Ich konnte nicht die aspectj-maven-plugin bekommen, um den Aspekt der "binären" Weg richtig zu weben, so dass ich stattdessen das Plugin jcabi-maven-plugin verwendet. Siehe http://plugin.jcabi.com/example-ajc.html

The Pom die für mich gearbeitet:

<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 funktioniert das mit den Aspekten und einige Anmerkungen in Java definiert und dann mit diesen Anmerkungen Kotlin Methoden und Klassen zu annotieren , um die Aspekte erfolgreich in den Kotlin-Code zu injizieren.

Beachten Sie, dass, wenn die Kotlin-Datei sowohl eine Hauptmethode als auch eine Klasse in derselben Datei definiert hat, der Kotlin-Compiler zwei Klassendateien erzeugt. Eine Klasse mit dem Namen der Klasse und eine Klasse mit "Kt" hinzugefügt zu seinem Namen. Gut zu wissen, wenn Sie versuchen, das Exec-Maven-Plugin zu verwenden, um den Kotlin-Code auszuführen.

Allerdings spielte dies mit Eclipse nicht sehr gut. Vielleicht wird IntelliJ hier einen besseren Job machen.

+1

Gibt es ein Beispiel für die Verwendung von aspectj in Kotlin? Ich habe das versucht, aber es hat nicht funktioniert. – junk

3

Zusätzlich zu den anderen Kommentaren/Antworten denke ich, es ist erwähnenswert, dass Sie Code vor/nach/um Funktionscode "weben" können, indem Sie inline functions verwenden. z.B .:

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") 
} 

Sie keinen Zugriff auf alle Informationen haben, dass AspectJ gibt Ihnen aber für einfache Fälle, in denen man einfach wiederverwenden möchten einige Code ausgeführt wird vor/nach/über einen anderen Code dies ganz gut funktioniert.