Kotlin 1.1.1 与 1.2.30 和 AspectJ
Kotlin 1.1.1 vs 1.2.30 & AspectJ
我正在尝试将 Kotlin 1.2.30 与 AspectJ 一起使用(使用以下 AspectJ gradle 插件:github repo,与作者无关)。我的构建 gradle 似乎适用于旧版本的 kotlin(例如 1.1.1),但不适用于 1.2 版本。
我正在尝试向以下 Main.kt 文件添加方面:
package test
fun main (args: Array<String>) {
object {
fun foo () { print("foo")}
}.foo()
}
我的方面文件,AspectTest.kt如下:
package test
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
@Aspect
class AspectTest {
@Around("execution (* *())")
fun around(joinPoint: ProceedingJoinPoint) : Any? {
println("joinpoint")
return joinPoint.proceed();
}
}
我的build.gradle是:
buildscript {
ext.kotlin_version = '1.2.30'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.sedovalx.gradle:gradle-aspectj-binary:1.0.25"
}
}
group 'test'
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.sedovalx.gradle-aspectj-binary'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
compile ("org.aspectj:aspectjrt:1.9.1")
compile 'org.aspectj:aspectjweaver:1.9.1'
compile 'org.slf4j:slf4j-simple:1.7.21'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
mainClassName ='test.MainKt'
weaveClasses.dependsOn compileJava
classes.dependsOn weaveClasses
当我 运行 使用 kotlin_version = 1.1.1
的代码时,它可以工作并打印:
joinpoint
foo
如果是 Kotlin 1.2.30(或我尝试过的 1.2 分支中的任何其他版本),则会打印“foo”,就好像这方面不起作用一样。
如果 kotlin 版本较新,我该如何解决这个问题?
问题的原因是 kotlin 1.1.1 将 kotlin classes 编译为 build/classes/java
,而 kotlin 1.2.30 将 .class 文件编译为 build/classes/kotlin
。我使用的 AspectJ gradle plugin 从 sourceSets.main.output.classesDir
目录读取 .class 文件进行编织,默认情况下该目录设置为 build/classes/java
并且我的项目中没有文件。我认为插件作者应该更改其代码以使用 sourceSets.main.output.classesDirs
代替,这允许许多 .class 输出目录,这在多语言项目中尤为重要。
尽管如此,我通过将 sourceSets.main.output.classesDir=sourceSets.main.output.classesDir.toString().replace("java", "kotlin")
行添加到我的 build.gradle
以一种 hacky 的方式解决了 1.2.30 kotlin 不兼容的问题
与 gradle 没有太大关系,但我认为您也应该能够使用 gradle 进行这项工作。我已经使用 kotlin (1.3.40) + aspectj (1.9.1) + maven 制作了一个示例项目(有两个不同的插件可以简化 maven 构建的编织,两者似乎都工作正常)。你可以在这里查看:https://github.com/serpro69/kotlin-aspectj-maven-example
我正在尝试将 Kotlin 1.2.30 与 AspectJ 一起使用(使用以下 AspectJ gradle 插件:github repo,与作者无关)。我的构建 gradle 似乎适用于旧版本的 kotlin(例如 1.1.1),但不适用于 1.2 版本。
我正在尝试向以下 Main.kt 文件添加方面:
package test
fun main (args: Array<String>) {
object {
fun foo () { print("foo")}
}.foo()
}
我的方面文件,AspectTest.kt如下:
package test
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
@Aspect
class AspectTest {
@Around("execution (* *())")
fun around(joinPoint: ProceedingJoinPoint) : Any? {
println("joinpoint")
return joinPoint.proceed();
}
}
我的build.gradle是:
buildscript {
ext.kotlin_version = '1.2.30'
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.github.sedovalx.gradle:gradle-aspectj-binary:1.0.25"
}
}
group 'test'
version '1.0-SNAPSHOT'
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.sedovalx.gradle-aspectj-binary'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12'
compile ("org.aspectj:aspectjrt:1.9.1")
compile 'org.aspectj:aspectjweaver:1.9.1'
compile 'org.slf4j:slf4j-simple:1.7.21'
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
mainClassName ='test.MainKt'
weaveClasses.dependsOn compileJava
classes.dependsOn weaveClasses
当我 运行 使用 kotlin_version = 1.1.1
的代码时,它可以工作并打印:
joinpoint
foo
如果是 Kotlin 1.2.30(或我尝试过的 1.2 分支中的任何其他版本),则会打印“foo”,就好像这方面不起作用一样。
如果 kotlin 版本较新,我该如何解决这个问题?
问题的原因是 kotlin 1.1.1 将 kotlin classes 编译为 build/classes/java
,而 kotlin 1.2.30 将 .class 文件编译为 build/classes/kotlin
。我使用的 AspectJ gradle plugin 从 sourceSets.main.output.classesDir
目录读取 .class 文件进行编织,默认情况下该目录设置为 build/classes/java
并且我的项目中没有文件。我认为插件作者应该更改其代码以使用 sourceSets.main.output.classesDirs
代替,这允许许多 .class 输出目录,这在多语言项目中尤为重要。
尽管如此,我通过将 sourceSets.main.output.classesDir=sourceSets.main.output.classesDir.toString().replace("java", "kotlin")
行添加到我的 build.gradle
与 gradle 没有太大关系,但我认为您也应该能够使用 gradle 进行这项工作。我已经使用 kotlin (1.3.40) + aspectj (1.9.1) + maven 制作了一个示例项目(有两个不同的插件可以简化 maven 构建的编织,两者似乎都工作正常)。你可以在这里查看:https://github.com/serpro69/kotlin-aspectj-maven-example