Closed stupidTiecha closed 4 years ago
由于 Kotlin MPP 目前无法使用任何 Java 代码,我无法进行 Java 的测试...
我发现换成1.0-EA2后,依然会发生以上异常
由于 Kotlin MPP 目前无法使用任何 Java 代码,我无法进行 Java 的测试... 看看这个?
UPDATE: In newer versions of Kotlin you can use args.orEmpty() instead of args ?: emptyArray()
TL;DR You cannot pass args but you need to use *(args ?: emptyArray()) because Method.invoke does not expect an array but a variadic parameter.
See this answer for more information
The way I found the actual issue I looked at the generated bytecode, for Kotlin I get the following:
override fun invoke(proxy : Any?, method : Method, args : Array
public Object invoke(Object proxy, Method method, Object args[]) throws Throwable { System.out.println("Java handler works"); return method.invoke(target, args); } public java.lang.Object invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) throws java.lang.Throwable; Code: 0: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #4 // String Java handler works 5: invokevirtual #5 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 8: aload_2 9: aload_0 10: getfield #2 // Field target:LIface; 13: aload_3 14: invokevirtual #6 // Method java/lang/reflect/Method.invoke:(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; 17: areturn Now, let's intercept the actuall array. I created a method in Java code to act as an intermediary:
public static Object invoke0(Iface target, Method method, Object args[]) throws Throwable { System.out.println("Invoking method with " + java.util.Arrays.toString(args)); return method.invoke(target, args); } Execute that from both Java and Kotlin - and it works.
Now what is the difference? Right, we expect an Object[], but Method.invoke takes an Object....
Change our intermediary to take Object... and we get our error message, along with this output:
Invoking method with [[Ljava.lang.Object;@4b67cf4d] So obviously, we aren't passing an Object[] but an Object[][], which means type mismatch!
@javax.validation.constraints.NotNull
添加了注解依旧没用的
import javax.validation.constraints.NotNull;
@EventHandler
public ListeningStatus onFriendMsg (@NotNull FriendMessageEvent event) {
MessageReceipt<Contact> receipt = event.getSender().sendMessage("测试测试");
receipt.recallIn(10000);
return ListeningStatus.LISTENING;
}
仍然报错: 2020-07-17 14:00:12 E/Bot 1057814219: An exception was thrown under a coroutine of Bot java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.mamoe.mirai.event.Events__JvmMethodListenersKt$registerEvent$15$1.invokeSuspend(JvmMethodListeners.kt:368) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
@javax.validation.constraints.NotNull
添加了注解依旧没用的
import javax.validation.constraints.NotNull; @EventHandler public ListeningStatus onFriendMsg (@NotNull FriendMessageEvent event) { MessageReceipt<Contact> receipt = event.getSender().sendMessage("测试测试"); receipt.recallIn(10000); return ListeningStatus.LISTENING; }
仍然报错: 2020-07-17 14:00:12 E/Bot 1057814219: An exception was thrown under a coroutine of Bot java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.mamoe.mirai.event.Events__JvmMethodListenersKt$registerEvent$15$1.invokeSuspend(JvmMethodListeners.kt:368) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
我这边经测试没有问题. 检查下该注解的版本. 这是我这边的依赖版本.
依赖版本相同的 感觉不是这个的问题
Exception in thread "main" java.lang.IllegalArgumentException: Kotlin event handlers cannot have nullable parameter type.
at net.mamoe.mirai.event.Events__JvmMethodListenersKt.registerEvent$Events__JvmMethodListenersKt(JvmMethodListeners.kt:298)
at net.mamoe.mirai.event.Events__JvmMethodListenersKt.registerEvents(JvmMethodListeners.kt:233)
at net.mamoe.mirai.event.Events.registerEvents(JvmMethodListeners.kt:1)
at net.mamoe.mirai.event.Events__JvmMethodListenersKt.registerEvents$default(JvmMethodListeners.kt:230)
at net.mamoe.mirai.event.Events.registerEvents$default(JvmMethodListeners.kt:1)
at net.mamoe.mirai.event.Events.registerEvents(JvmMethodListeners.kt)
at Test.main(Test.java:35)
这个是为啥
@javax.validation.constraints.NotNull
添加了注解依旧没用的
import javax.validation.constraints.NotNull; @EventHandler public ListeningStatus onFriendMsg (@NotNull FriendMessageEvent event) { MessageReceipt<Contact> receipt = event.getSender().sendMessage("测试测试"); receipt.recallIn(10000); return ListeningStatus.LISTENING; }
仍然报错: 2020-07-17 14:00:12 E/Bot 1057814219: An exception was thrown under a coroutine of Bot java.lang.IllegalArgumentException: argument type mismatch at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at net.mamoe.mirai.event.Events__JvmMethodListenersKt$registerEvent$15$1.invokeSuspend(JvmMethodListeners.kt:368) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
我这边经测试没有问题. 检查下该注解的版本. 这是我这边的依赖版本.
依赖版本相同的 感觉不是这个的问题
不好意思哈, 眼误理解错问题定位了... 匿名内部类的问题. 单独拎一个类定义实现SimpleListenerHost类即可.
public static void main(String[] args) {
Bot bot = BotFactoryJvm.newBot(account, pwd, new BotConfiguration(){
{
fileBasedDeviceInfo("deviceInfo.json");
}
});
Events.registerEvents(bot, new CustomEventListener());
bot.login();
bot.join();
}
public static class CustomEventListener extends SimpleListenerHost{
@EventHandler
public ListeningStatus onFriendMsg (FriendMessageEvent event) {
MessageReceipt<Contact> receipt = event.getSender().sendMessage("测试测试");
receipt.recallIn(10000);
return ListeningStatus.LISTENING;
}
@Override
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
super.handleException(context, exception);
}
}
原因不明, 之前遇到过, 隔了段时间忘记提issue了.
@Him188 麻烦关下这个issue, 多谢. 我不小心把个人配置信息暴露出来了.
问题定位: SimpleListenerHost实现类是匿名内部类, 导致监听到事件上报时抛出 java.lang.IllegalArgumentException: argument type mismatch异常
解决方案: 不能走匿名内部类, 静态/非静态内部类&外部类声明即可.
回复可以自己删掉的
public static class CustomEventListener extends SimpleListenerHost{
@EventHandler
public ListeningStatus onFriendMsg (FriendMessageEvent event) {
MessageReceipt<Contact> receipt = event.getSender().sendMessage("测试测试");
receipt.recallIn(10000);
return ListeningStatus.LISTENING;
}
@Override
public void handleException(@javax.validation.constraints.NotNull CoroutineContext context,@javax.validation.constraints.NotNull Throwable exception) {
super.handleException(context, exception);
}
}
Exception in thread "main" java.lang.IllegalArgumentException: Kotlin event handlers cannot have nullable parameter type.
哎,我真的是太菜了
@stupidTiecha 请问你使用的 mirai 版本是多少?
@Him188 #mirai#1.1.2 目前还存在这个问题.
然而实际是listener host传参错误
已在 1.0-EA2 修复
Originally posted by @Him188 in https://github.com/mamoe/mirai/issues/412#issuecomment-653416239
jdk版本 1.8_162(Orecla) 和 1.8_252(openJdk)
代码片段:
堆栈信息: