【发布时间】:2011-09-19 14:14:25
【问题描述】:
我从 RMI 注册表获得远程引用;让我们称之为s。现在,s 是(接口)类型S,它提供了一个方法m(A, B, int)。
在客户端,我有A 和B 的实现,它们都扩展了UnicastRemoteObject(因此会自动导出)。分别考虑实例a 和b。
现在我打电话给m(a, b, 0)。它可以编译,但在运行时失败,信息量非常少
java.lang.IllegalArgumentException: argument type mismatch
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:305)
at sun.rmi.transport.Transport$1.run(Transport.java:159)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:155)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:255)
at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:233)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:142)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:178)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:132)
at $Proxy0.m(Unknown Source)
[... application specific sites]
遗憾的是,NativeMethodAccessorImpl.invoke0 是本机实现的,无法检查。所以,我完全不知所措。很明显,类型匹配,否则原代码应该编译不出来吧?
这可能是什么原因?
编辑:我们使用 Java 6。该错误可以在 Ubuntu 11.04 32bit、Ubuntu 10.10 64bit 和 Windows 7 32bit 上重现。
编辑 2: 我在 S 上实现了一些虚拟方法来测试各个参数。事实证明,s.n()、s.t0(b) 和 s.t1(0) 按预期工作;只有s.t2(a) 失败。这意味着我实现A 的方式有问题,不是吗?
A 和B 之间唯一显着的区别(当然,除了实际内容)是A 是一个扩展UnicastRemoteObject 的类,并且遵循远程接口的约定,但没有实现可区分的远程接口。 B 是一个远程接口,我通过了它的实现。
【问题讨论】:
-
我猜你在没有重新运行 rmic 的情况下改变了你的接口或实现类。
-
我们使用 Java 6,所以应该有 rmic 的需求。它自 1.5 以来一直是遗留的。
-
你在服务器端使用了哪些 A 和 B 的实现?
-
A的那个在服务器和客户端上都是一样的。B的那个只在客户端可用,服务器只知道接口B。 -
客户端和服务器是否有可能对接口'S'有不同的类文件?