【问题标题】:java.io.NotSerializableException while writing to Oracle Coherence cache写入 Oracle Coherence 缓存时出现 java.io.NotSerializableException
【发布时间】:2016-02-23 09:55:37
【问题描述】:

我有 2 个启用存储的缓存节点,我正尝试使用它们来预加载缓存。这 2 个启用存储的节点将加载大约 100 万个帐户。键和值都是String 我试图写入缓存的对象。我正在使用InvocationService.execute() 方法异步调用预加载任务:

for (Map.Entry<Member, LoaderInvocable> entry : mappedWork.entrySet()) {
    Member member = entry.getKey();
    LoaderInvocable task = entry.getValue();
    invocationService.execute(task, Collections.singleton(member), null);
}

LoaderInvocable 是一个实现InvocableSerializable 接口的类,它的run() 方法已被重写以执行从数据库读取和写入缓存的实际工作。

InvocationService 在 coherence 配置文件中定义如下:

<invocation-scheme>
      <scheme-name>
      InvocationScheme</scheme-name>
      <service-name>
      LoaderInvocationService</service-name>
      <autostart system-property="tangosol.coherence.invocation.autostart">true</autostart>
 </invocation-scheme>   

以下是我得到的例外:

2016-02-22 17:16:24,612 [pool-1-thread-1] ERROR (support.context.SessionExecutable) Caught exception from SessionExecutable.execute()
(Wrapped) java.io.NotSerializableException: com.oracle.common.collections.ConcurrentLinkedQueue
    at com.tangosol.util.Base.ensureRuntimeException(Base.java:289)
    at com.tangosol.util.Base.ensureRuntimeException(Base.java:270)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher.packetizeMessage(PacketPublisher.CDB:28)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher$InQueue.add(PacketPublisher.CDB:8)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.packetProcessor.PacketPublisher.post(PacketPublisher.CDB:1)
    at com.tangosol.coherence.component.net.Message.dispatch(Message.CDB:77)
    at com.tangosol.coherence.component.net.Message.post(Message.CDB:1)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.post(Grid.CDB:2)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.Grid.send(Grid.CDB:1)
    at com.tangosol.coherence.component.util.daemon.queueProcessor.service.grid.InvocationService.execute(InvocationService.CDB:33)
    at com.tangosol.coherence.component.util.safeService.SafeInvocationService.execute(SafeInvocationService.CDB:1)

。 . . . . .

Caused by: java.io.NotSerializableException: com.oracle.common.collections.ConcurrentLinkedQueue
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
    at java.util.Hashtable.writeObject(Hashtable.java:988)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
    at com.tangosol.coherence.Component.writeObject(Component.CDB:1)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:438)
    at com.tangosol.coherence.Component.writeObject(Component.CDB:1)

好像有一半的账号被缓存成功了。它可以是节点特定的问题吗?两个启用存储的缓存节点都位于使用相同集群配置的同一台服务器上。从日志中可以清楚地看出,两个节点都成功地加入了集群。

【问题讨论】:

  • 即使在同一台服务器上,invocable 也会通过网络从一个节点传输到另一个节点,因此需要可序列化。
  • 我的 LoaderInvocable 类已经是可序列化的,Paul。仍然收到错误。即使是我存储在缓存中的对象,也只是可以隐式序列化的字符串。
  • 请检查您的 LoaderInvocable 类实现 PofSerializer
  • 谢谢普拉文。我已经使用了 POF 序列化程序并且不再面临异常。但现在我面临一个新问题。

标签: preloading oracle-coherence notserializableexception


【解决方案1】:

感谢普拉文。我已经实现了PortableObject 接口,不再面对NotSerializableException。但现在我面临一个新问题。第二个节点没有调用任务并在日志中没有任何异常离开集群。

我使用了InvocationObserver,这表明memberLeft() 是集群。我对序列化的readExternal()writeExternal() 方法的实现是否有问题?下面是实现:

@Override
public void readExternal(PofReader paramPofReader) throws IOException {
    // TODO Auto-generated method stub

    cacheName = paramPofReader.readString(0);
    firstRow = paramPofReader.readLong(1);
    lastRow = paramPofReader.readLong(2);

}

@Override
public void writeExternal(PofWriter paramPofWriter) throws IOException {
    // TODO Auto-generated method stub
    paramPofWriter.writeString(0, cacheName);
    paramPofWriter.writeLong(1, firstRow);
    paramPofWriter.writeLong(2, lastRow);
}

【讨论】:

    猜你喜欢
    • 2013-06-19
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-30
    • 1970-01-01
    • 2013-09-30
    相关资源
    最近更新 更多