简体   繁体   English

Kotlin 中的简单反射在现有 Java 项目中不起作用

[英]Simple reflection in Kotlin doesn't work in existing Java project

I have simple Kotlin code in an existing Java project我在现有的 Java 项目中有简单的 Kotlin 代码

class A(val p: Int)

fun main() {
    println("Hello World")
    println(A::javaClass)
    println(A::p)
}

However, this throws an exception但是,这会引发异常

Exception in thread "main" java.lang.NoSuchMethodError: 'void kotlin.jvm.internal.PropertyReference1Impl.<init>(java.lang.Class, java.lang.String, java.lang.String, int)'
    at mloop.kt.graphql.TestKt$main$1.<init>(Test.kt)
    at mloop.kt.graphql.TestKt$main$1.<clinit>(Test.kt)
    at mloop.kt.graphql.TestKt.main(Test.kt:10)
    at mloop.kt.graphql.TestKt.main(Test.kt)

build.gradle.kts is also simple build.gradle.kts也很简单

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    kotlin("jvm") version "1.7.20"
}

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect:1.7.20")
}

tasks.test {
    useJUnitPlatform()
}

tasks.withType<KotlinCompile> {
    kotlinOptions.jvmTarget = "17"
}

Verified that kotlin-reflect is also listed in runtimeClassPath.已验证 kotlin-reflect 也在 runtimeClassPath 中列出。 However, the same code works in a Kotlin-only project.但是,相同的代码在仅限 Kotlin 的项目中有效。

compileClasspath - Compile classpath for compilation 'main' (target  (jvm)).
+--- org.slf4j:slf4j-api -> 2.0.3
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20
|    +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20
|    |    +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.7.20
+--- org.jetbrains.kotlin:kotlin-reflect:1.7.20
|    \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20 (*)
\--- org.projectlombok:lombok:1.18.24

runtimeClasspath - Runtime classpath of compilation 'main' (target  (jvm)).
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.20
|    +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20
|    |    +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.7.20
+--- org.jetbrains.kotlin:kotlin-reflect:1.7.20
|    \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.20 (*)
+--- org.jetbrains.kotlin:kotlin-reflect:{strictly 1.7.20} -> 1.7.20 (c)
+--- org.jetbrains.kotlin:kotlin-stdlib:{strictly 1.7.20} -> 1.7.20 (c)
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:{strictly 1.7.20} -> 1.7.20 (c)
+--- org.jetbrains.kotlin:kotlin-stdlib-common:{strictly 1.7.20} -> 1.7.20 (c)

Use ::class.java instead of ::javaClass .使用::class.java而不是::javaClass

The documentation isn't clear about this, but you don't need the kotlin-reflect library for basic property, function, and class references.文档对此并不清楚,但您不需要kotlin-reflect库来获取基本属性、function 和 class 引用。 You only need it for the deeper features like getting the class/property/function members or descriptors.你只需要它来获得更深层次的特性,比如获取类/属性/函数成员或描述符。 Passing around KClasses, KProperties, and KFunction instances or invoking them doesn't require the library.传递 KClasses、KProperties 和 KFunction 实例或调用它们不需要库。

This sounds more like a mismatch in the kotlin stdlib during runtime and a compiled class, not something related to reflection (but I'm not very familiar with reflection so I could be wrong).这听起来更像是运行时 kotlin stdlib 与编译后的 class 不匹配,与反射无关(但我对反射不是很熟悉,所以我可能是错的)。

It seems like the method with signature好像是带签名的方法

PropertyReference1Impl(java.lang.Class, java.lang.String, java.lang.String, int)

Was added in kotlin 1.4 , also see this for another example of the same error.已在kotlin 1.4中添加,另请参阅以了解相同错误的另一个示例。

Not really sure where you kotlin < 1.4 stuff is coming from though, are you perhaps using an old gradle version (although I'm not even sure if that would matter)?不太确定你 kotlin < 1.4的东西是从哪里来的,你是否使用旧的 gradle 版本(虽然我什至不确定这是否重要)?

Please also add the full stacktrace to the question, instead of just 1 line, that should show what exactly is attempting to call the missing method.还请将完整的堆栈跟踪添加到问题中,而不仅仅是 1 行,它应该显示究竟是什么试图调用丢失的方法。

After lot of dependancy scrutiny, I figured out com.newrelic.logging:logback:2.5.0 was breaking the java <-> kotlin reflection, upgrading to 2.6.0 fixed it.经过大量的依赖性审查,我发现com.newrelic.logging:logback:2.5.0破坏了 java <-> kotlin 反射,升级到 2.6.0 修复了它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM