org.springframework.remoting.RemoteAccessException: Could not access HTTP invoker remote service at [ http://xxx/xxxService]; nested exception is java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: java.util.RandomAccessSubList
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessException(HttpInvokerClientInterceptor.java:211)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:144)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
......
看日志应该是有一个类未实现序列化接口导致的,浏览了代码,也没发现有什么异常的。然后就开始跟踪这个类:RandomAccessSubList, 终于发现ArrayList实例在调用subList方式是,返回的就是这个类,代码如下(AbstractList.java):
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}
显然就是类RandomAccessSubList未实现序列化接口,由此得到一个写RMI服务需要注意的地方:返回对象不能包含通过调用subList方法得到的结果,否则会抛出该异常。为了避免这个缺陷,有两种方法:
1. 通过hessian等远程调用方式绕开RMI
2. 不直接调用subList,实现一个自己的类似方法即可。
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.convertHttpInvokerAccessException(HttpInvokerClientInterceptor.java:211)
at org.springframework.remoting.httpinvoker.HttpInvokerClientInterceptor.invoke(HttpInvokerClientInterceptor.java:144)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
......
看日志应该是有一个类未实现序列化接口导致的,浏览了代码,也没发现有什么异常的。然后就开始跟踪这个类:RandomAccessSubList, 终于发现ArrayList实例在调用subList方式是,返回的就是这个类,代码如下(AbstractList.java):
public List<E> subList(int fromIndex, int toIndex) {
return (this instanceof RandomAccess ?
new RandomAccessSubList<E>(this, fromIndex, toIndex) :
new SubList<E>(this, fromIndex, toIndex));
}
显然就是类RandomAccessSubList未实现序列化接口,由此得到一个写RMI服务需要注意的地方:返回对象不能包含通过调用subList方法得到的结果,否则会抛出该异常。为了避免这个缺陷,有两种方法:
1. 通过hessian等远程调用方式绕开RMI
2. 不直接调用subList,实现一个自己的类似方法即可。